1. When deploying EJB, it has a name(if specified using annotation : @Stateless(name="SessionEJB") or if descriptor: <ejb-name>SessionEJB</ejb-name>.
2. This EJB deployed to OC4J. Now to do a lookup for this EJB, we can use either ApplicationClientInitialContextFactory or RMIInitialContextFactory.
3. In case of RMIInitialContextFactory, no need of application-client.xml and the context lookup will be : new InitialContext.lookup("SessionEJB").
4. In case of ApplicationClientInitialContextFactory, we need application-client.xml. It has to introduce the ejb refrence going to be used in code as:
<application-client xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd" version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee">
<display-name>InterceptorTest-app-client</display-name>
<ejb-ref>
<ejb-ref-name>ejb/SessionEJB</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<remote>myEJB.SessionEJB</remote>
<ejb-link>SessionEJB</ejb-link>
</ejb-ref>
</application-client>
5. Here, ejb-link is used to link to the actual bean. Now, in the client code we use the ejb-ref-name for lookup as:
new InitialContext().lookup("java:comp/env/ejb/SessionEJB");
Showing posts with label Java EE. Show all posts
Showing posts with label Java EE. Show all posts
Thursday, December 28, 2006
Sunday, December 24, 2006
MDB deployment in OC4J
1. Create the MDB(normal java class with @MessageDriven annotation). Set the ActivationConfigs.
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/TopicConnectionFactory"),
@ActivationConfigProperty(propertyName="destinationName",
propertyValue="jms/demoTopic"),
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(propertyName="messageSelector", propertyValue="RECIPIENT = 'MDB'") } )
2. Create EJB jar deployment profile(MDBServer.deploy) for the above MDB and deploy it to OC4J server(application name = MDBServer)
3. In same project, create the MDBClient. Inject the resources @Resource(name="jms/demoQueue") and @Resource(name="jms/TopicConnectionFactory"). Use connectionFactory and create connection, then session, message and send the message using producer.
4. In Jdeveloper create jndi.properties file with:
java.naming.factory.initial= oracle.j2ee.naming.ApplicationClientInitialContextFactory
java.naming.provider.url=ormi://localhost:23791/MDBServer
java.naming.security.principal=oc4jadmin
java.naming.security.credentials=welcome
5. Create client Jar deployment profile from Jdeveloper. This creates application-client.xml. Modify application-client.xml and add following lines for the resource reference entries(Make sure to mention the main class file name in descriptor creation)
<application-client xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd" version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee">
<display-name>MDB1-app-client</display-name>
<resource-env-ref>
<resource-env-ref-name>jms/demoTopic</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
</resource-env-ref>
<resource-env-ref>
<resource-env-ref-name>jms/TopicConnectionFactory </resource-env-ref-name>
<resource-env-ref-type>javax.jms.TopicConnectionFactory </resource-env-ref-type>
</resource-env-ref>
</application-client>
6. Deploy the deployment profile MDBClient.deploy to MDBClient.jar.
7. From command prompt containing the jar file, set class path and run :
D:\installs\JdevStudio10131\jdev\mywork\MDB\MDB1\deploy>set CLASSPATH =.\;D:\installs\oc4j\j2ee\home\oc4jclient.jar;D:\installs\oc4j\j2ee\home\lib\javax77.jar;
D:\installs\JdevStudio10131\jdev\mywork\MDB\MDB1\deploy>java oracle.oc4j.appclient.AppClientContainer MDBClient.jar
Output from the application server log will contain:
06/12/24 20:26:44 onMessage() - Message[ID:Oc4jJMS.Message.krishnamoorthy.64e0c3
ab:10fb4f6b670:-8000.4]
onMessage method of the MDB just does a system.out.println(message)
Note: Without creating jar of client files and if I directly run using:
D:\installs\JdevStudio10131\jdev\mywork\MDB\MDB1\classes>java -Djava.naming.factory.initial=oracle.j2ee.naming.ApplicationClientInitialContextFactory -Djava.naming.provider.url=ormi://localhost:23791/MDBServer -Djava.naming.security.principal=oc4jadmin -Djava.naming.security.credentials=welcome myJMSClient.TestJMSClient
I get
Exception in thread "main" java.lang.NullPointerException
at myJMSClient.TestJMSClient.main(TestJMSClient.java:22)
So, should a JMS client be run always using AppClientContainer as :
java oracle.oc4j.appclient.AppClientContainer MDBClient.jar
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/TopicConnectionFactory"),
@ActivationConfigProperty(propertyName="destinationName",
propertyValue="jms/demoTopic"),
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(propertyName="messageSelector", propertyValue="RECIPIENT = 'MDB'") } )
2. Create EJB jar deployment profile(MDBServer.deploy) for the above MDB and deploy it to OC4J server(application name = MDBServer)
3. In same project, create the MDBClient. Inject the resources @Resource(name="jms/demoQueue") and @Resource(name="jms/TopicConnectionFactory"). Use connectionFactory and create connection, then session, message and send the message using producer.
4. In Jdeveloper create jndi.properties file with:
java.naming.factory.initial= oracle.j2ee.naming.ApplicationClientInitialContextFactory
java.naming.provider.url=ormi://localhost:23791/MDBServer
java.naming.security.principal=oc4jadmin
java.naming.security.credentials=welcome
5. Create client Jar deployment profile from Jdeveloper. This creates application-client.xml. Modify application-client.xml and add following lines for the resource reference entries(Make sure to mention the main class file name in descriptor creation)
<application-client xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd" version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee">
<display-name>MDB1-app-client</display-name>
<resource-env-ref>
<resource-env-ref-name>jms/demoTopic</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
</resource-env-ref>
<resource-env-ref>
<resource-env-ref-name>jms/TopicConnectionFactory </resource-env-ref-name>
<resource-env-ref-type>javax.jms.TopicConnectionFactory </resource-env-ref-type>
</resource-env-ref>
</application-client>
6. Deploy the deployment profile MDBClient.deploy to MDBClient.jar.
7. From command prompt containing the jar file, set class path and run :
D:\installs\JdevStudio10131\jdev\mywork\MDB\MDB1\deploy>set CLASSPATH =.\;D:\installs\oc4j\j2ee\home\oc4jclient.jar;D:\installs\oc4j\j2ee\home\lib\javax77.jar;
D:\installs\JdevStudio10131\jdev\mywork\MDB\MDB1\deploy>java oracle.oc4j.appclient.AppClientContainer MDBClient.jar
Output from the application server log will contain:
06/12/24 20:26:44 onMessage() - Message[ID:Oc4jJMS.Message.krishnamoorthy.64e0c3
ab:10fb4f6b670:-8000.4]
onMessage method of the MDB just does a system.out.println(message)
Note: Without creating jar of client files and if I directly run using:
D:\installs\JdevStudio10131\jdev\mywork\MDB\MDB1\classes>java -Djava.naming.factory.initial=oracle.j2ee.naming.ApplicationClientInitialContextFactory -Djava.naming.provider.url=ormi://localhost:23791/MDBServer -Djava.naming.security.principal=oc4jadmin -Djava.naming.security.credentials=welcome myJMSClient.TestJMSClient
I get
Exception in thread "main" java.lang.NullPointerException
at myJMSClient.TestJMSClient.main(TestJMSClient.java:22)
So, should a JMS client be run always using AppClientContainer as :
java oracle.oc4j.appclient.AppClientContainer MDBClient.jar
Friday, December 22, 2006
Running EJB Client Standalone
HelloWorld.java
package myEJB;
import javax.ejb.Remote;
@Remote
public interface HelloWorld {
public String sayHello(String name);
}
HelloWorldBean.java
package myEJB;
import javax.ejb.Stateless;
@Stateless
public class HelloWorldBean implements HelloWorld {
private int count;
public String sayHello(String name) {
count++;
System.out.println("sayHello method from Bean ");
return "Hello " + name + " Count : " + count;
}
}
Compile the classes and run in embedded oc4j of jdeveloper. Or create a ejb jar deployment profile and deploy it to standalone oc4j server. Deployment name is the application name in the standalone oc4j. Let us say application is HelloWorldDeploy. Ear file contains jar file and META-INF. Inside META-INF is the application.xml containing the name of ejb module jar file. Jar file contains the interface and bean classes. After deploying, create a test client as follows:
HelloWorldClient.java
package myEJB;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class HelloWorldClient {
public static void main(String [] args) {
try {
final Context context = new InitialContext();
HelloWorld helloWorld = (HelloWorld)context.lookup("java:comp/env/ejb/HelloWorldBean");
// Call any of the Remote methods below to access the EJB
System.out.println(helloWorld.sayHello( "Krishna" ));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
To invoke ejb method from command line:
D:\work\MyWork\ejb\ejb3>set CLASSPATH=D:\installs\JdevStudio10131\j2ee\home\oc4jclient.jar;.\;
D:\work\MyWork\ejb\ejb3>java -Djava.naming.factory.initial=oracle.j2ee.naming.Ap
plicationClientInitialContextFactory -Djava.naming.provider.url=ormi://localhost
:23791/HelloWorldDeploy -Djava.naming.security.principal=oc4jadmin -Djava.naming
.security.credentials=welcome myEJB.HelloWorldClient
Output is : Hello Krishna Count : 1
package myEJB;
import javax.ejb.Remote;
@Remote
public interface HelloWorld {
public String sayHello(String name);
}
HelloWorldBean.java
package myEJB;
import javax.ejb.Stateless;
@Stateless
public class HelloWorldBean implements HelloWorld {
private int count;
public String sayHello(String name) {
count++;
System.out.println("sayHello method from Bean ");
return "Hello " + name + " Count : " + count;
}
}
Compile the classes and run in embedded oc4j of jdeveloper. Or create a ejb jar deployment profile and deploy it to standalone oc4j server. Deployment name is the application name in the standalone oc4j. Let us say application is HelloWorldDeploy. Ear file contains jar file and META-INF. Inside META-INF is the application.xml containing the name of ejb module jar file. Jar file contains the interface and bean classes. After deploying, create a test client as follows:
HelloWorldClient.java
package myEJB;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class HelloWorldClient {
public static void main(String [] args) {
try {
final Context context = new InitialContext();
HelloWorld helloWorld = (HelloWorld)context.lookup("java:comp/env/ejb/HelloWorldBean");
// Call any of the Remote methods below to access the EJB
System.out.println(helloWorld.sayHello( "Krishna" ));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
To invoke ejb method from command line:
D:\work\MyWork\ejb\ejb3>set CLASSPATH=D:\installs\JdevStudio10131\j2ee\home\oc4jclient.jar;.\;
D:\work\MyWork\ejb\ejb3>java -Djava.naming.factory.initial=oracle.j2ee.naming.Ap
plicationClientInitialContextFactory -Djava.naming.provider.url=ormi://localhost
:23791/HelloWorldDeploy -Djava.naming.security.principal=oc4jadmin -Djava.naming
.security.credentials=welcome myEJB.HelloWorldClient
Output is : Hello Krishna Count : 1
Thursday, December 21, 2006
Transaction Isolation Level
Good link for getting a refresh on the isolation level: http://www.oracle.com/technology/oramag/oracle/05-nov/o65asktom.html
Oracle supports READ COMMITTED and SERIALIZABLE. Oracle doesn't allow dirty reads(READ UNCOMMITTED). It allows a third isolation level which is READ ONLY. No insert, update, delete can be done in this mode.
Oracle supports READ COMMITTED and SERIALIZABLE. Oracle doesn't allow dirty reads(READ UNCOMMITTED). It allows a third isolation level which is READ ONLY. No insert, update, delete can be done in this mode.
Wednesday, December 20, 2006
RMI tutorial on SUN
1. Start the rmiregistry at the default port 1099. (rmiregistry.exe)
2. Start the Local Http server for delivering class files between server-RMI and RMI-Client.
D:\work\MyWork\rmi\suntutorial>java examples.classServer.ClassFileServer 1185 D:\work\MyWork\rmi\suntutorial
3. Then start the ComputeEngine server using :
D:\work\MyWork\rmi\suntutorial>java -cp .\;compute.jar -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/ -Djava.rmi.server.hostname=pc-krsethur-in -Djava.security.policy=D:\work\MyWork\rmi\suntutorial\server.policy engine.ComputeEngine
4. Remove the client files from the suntutorial folder and place it in a folder named test under this suntutorial so that RMI will get the files using http from the client(thus, the above classpath doesn't include the client classes).
5. server.policy should have the line
grant {
permission java.net.SocketPermission "*:*", "listen,accept,connect";
};
for the binding of remote object to the registry(1099).
6. Now run the client as
D:\work\MyWork\rmi\suntutorial\test>java -cp .\;..\compute.jar; -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/test/ -Djava.security.policy=D:\work\MyWork\rmi\suntutorial\client.policy client.ComputePi pc-krsethur-in 45
Output
3.141592653589793238462643383279502884197169399
7. Client.policy should have similar line above(5)
8. here -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/test/ will be set because during client execution, we call executeTask on the proxy remote object. The remote object running in the RMI runtime will delegate to the task object. Now, the task object is still not present in the RMI runtime and will give class not found exception. To prevent that we set the codebase to http://pc-krsethur-in:1185/test/. Here pc-krsethur-in:1185 will deliver files present under D:\work\MyWork\rmi\suntutorial. However, the task class is present in D:\work\MyWork\rmi\suntutorial\test folder. Hence, we append the test/ in the URL for the codebase. Our local file server will serve the classes from D:\work\MyWork\rmi\suntutorial\test for RMI runtime during client execution. Similarly, when the server was started, during binding of remote object, the interface classes(Compute.class and Task.class) for the RMI runtime was served by -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/.
9. After a single execution of both server and client, the classes(Compute.class and Task.class) for the server execution and the class(Task.class) from client execution will be present in the RMI runtime and hence if the local file server is stopped at this time and the server is aborted and restarted, it will work fine without any error about class not found. Similarly if the client is run now also, the client will work fine, because the Task.class is already loaded in the RMI runtime.
10. Now if we stop the rmiregistry.exe(thus all the classes loaded in RMI runtime are gone) and restart the rmiregistry and then start the server or client(with the local file server stopped), they will fail with class not found exception.
2. Start the Local Http server for delivering class files between server-RMI and RMI-Client.
D:\work\MyWork\rmi\suntutorial>java examples.classServer.ClassFileServer 1185 D:\work\MyWork\rmi\suntutorial
3. Then start the ComputeEngine server using :
D:\work\MyWork\rmi\suntutorial>java -cp .\;compute.jar -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/ -Djava.rmi.server.hostname=pc-krsethur-in -Djava.security.policy=D:\work\MyWork\rmi\suntutorial\server.policy engine.ComputeEngine
4. Remove the client files from the suntutorial folder and place it in a folder named test under this suntutorial so that RMI will get the files using http from the client(thus, the above classpath doesn't include the client classes).
5. server.policy should have the line
grant {
permission java.net.SocketPermission "*:*", "listen,accept,connect";
};
for the binding of remote object to the registry(1099).
6. Now run the client as
D:\work\MyWork\rmi\suntutorial\test>java -cp .\;..\compute.jar; -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/test/ -Djava.security.policy=D:\work\MyWork\rmi\suntutorial\client.policy client.ComputePi pc-krsethur-in 45
Output
3.141592653589793238462643383279502884197169399
7. Client.policy should have similar line above(5)
8. here -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/test/ will be set because during client execution, we call executeTask on the proxy remote object. The remote object running in the RMI runtime will delegate to the task object. Now, the task object is still not present in the RMI runtime and will give class not found exception. To prevent that we set the codebase to http://pc-krsethur-in:1185/test/. Here pc-krsethur-in:1185 will deliver files present under D:\work\MyWork\rmi\suntutorial. However, the task class is present in D:\work\MyWork\rmi\suntutorial\test folder. Hence, we append the test/ in the URL for the codebase. Our local file server will serve the classes from D:\work\MyWork\rmi\suntutorial\test for RMI runtime during client execution. Similarly, when the server was started, during binding of remote object, the interface classes(Compute.class and Task.class) for the RMI runtime was served by -Djava.rmi.server.codebase=http://pc-krsethur-in:1185/.
9. After a single execution of both server and client, the classes(Compute.class and Task.class) for the server execution and the class(Task.class) from client execution will be present in the RMI runtime and hence if the local file server is stopped at this time and the server is aborted and restarted, it will work fine without any error about class not found. Similarly if the client is run now also, the client will work fine, because the Task.class is already loaded in the RMI runtime.
10. Now if we stop the rmiregistry.exe(thus all the classes loaded in RMI runtime are gone) and restart the rmiregistry and then start the server or client(with the local file server stopped), they will fail with class not found exception.
Wednesday, August 30, 2006
KeepResident plugin for Eclipse/Jdeveloper
Jdeveloper being slow when shifting the application in windows. Reason being the windows swapping the jdeveloper memory even when large amount of physical memory is available.Application has a working set size. The default value is much too small for big Java applications like Eclipse. Hence, windows does a swapping. To prevent this, one thing that can be done is to increase the minimum water mark of this working set size. Then, there is another problem that when the user memory is less than the minimum working set size, windows will think that the application is not used and will do swapping again. Using VirtualLock() will prevent this and force Windows to keep Eclipse in memory.
Got this information from the blog : http://www.orablogs.com/gdavison/archives/001659.html
FAQ on this plugin also provides a clear information : http://suif.stanford.edu/pub/keepresident/faq.html
Got this information from the blog : http://www.orablogs.com/gdavison/archives/001659.html
FAQ on this plugin also provides a clear information : http://suif.stanford.edu/pub/keepresident/faq.html
Thursday, August 24, 2006
SOA Suite - Developer Preview
SOA Suite developer preview is available from : http://www.oracle.com/technology/software/products/ias/soapreview.html
Documentation for SOA, ESB, BPEL available from : http://download-east.oracle.com/otn_hosted_doc/soa/docs/index.htm
Documentation for SOA, ESB, BPEL available from : http://download-east.oracle.com/otn_hosted_doc/soa/docs/index.htm
WSIF Notes
- The Web Services Invocation Framework (WSIF) is a simple Java API for invoking Web services, no matter how or where the services are provided.
- WSIF enables developers to interact with abstract representations of Web services through their WSDL descriptions instead of working directly with the Simple Object Access Protocol (SOAP) APIs, which is the usual programming model.
- WSIF allows stubless or completely dynamic invocation of a Web service, based upon examination of the meta-data about the service at runtime. It also allows updated implementations of a binding to be plugged into WSIF at runtime, and it allows the calling service to defer choosing a binding until runtime.
- The separation of the API from the actual protocol also means you have flexibility - you can switch protocols, location, etc. without having to even recompile your client code.
- So if your an externally available SOAP service becomes available as an EJB, you can switch to using RMI/IIOP by just changing the service description (the WSDL), without having to make any modification in applications that use the service.
- You can exploit WSDL's extensibility, its capability to offer multiple bindings for the same service, deciding on a binding at runtime, etc.
- In the WSDL specification, Web service binding descriptions are extensions to the specification. So the SOAP binding, for example, is one way to expose the abstract functionality (and there could be others). Since WSIF mirrors WSDL very closely, it also views SOAP as just one of several ways you might wish to expose your software's functionality. WSDL thus becomes a normalized description of software, and WSIF is the natural client programming model.
- The WSIF API allows clients to invoke services focusing on the abstract service description - the portion of WSDL that covers the port types, operations and message exchanges without referring to real protocols.
- The abstract invocations work because they are backed up by protocol-specific pieces of code called providers. A provider is what conducts the actual message exchanges according to the specifics of a particular protocol - for example, the SOAP provider that is packaged with WSIF uses a specific SOAP engine like Axis to do the real work.
- The decoupling of the abstract invocation from the real provider that does the work results in a flexible programming model that allows dynamic invocation, late binding, clients being unaware of large scale changes to services - such as service migration, change of protocols, etc.
- WSIF also allows new providers to be registered dynamically, so you could enhance your client's capability without ever having to recompile its code or redeploy it.
- A provider is a piece of code that supports a WSDL extension and allows invocation of the service through that particular implementation. WSIF providers use the J2SE JAR service provider specification making them discoverable at runtime.
- Some bindings for which provider is available : java, ejb, jms, jca
WSDL Notes from W3C Spec
- WSDL is an XML format for describing network services as a set of endpoints operating on messages containing either document-oriented or procedure-oriented information.
- Elements in WSDL:
- Types - a container for data type definitions using some type system (such as XSD).
- Message – an abstract, typed definition of the data being communicated.
- Operation – an abstract description of an action supported by the service.
- Port Type – an abstract set of operations supported by one or more endpoints.
- Binding – a concrete protocol and data format specification for a particular port type.
- Port – a single endpoint defined as a combination of a binding and a network address.
- Service – a collection of related endpoints.
- WSDL doesn't introduce a type definition language. Supports XSD as canonical type system. Allows using other type definition languages via extensibility.
- Binding mechanism is used to attach a specific protocol or data format or structure to an abstract message or operation or end point.
- It introduces specific binding extensions for the following protocols and message format : SOAP 1.1, HTTP GET/POST, MIME. Other binding extensions can also be used.
- Message definitions are always considered to be an abstract definition of the message content. A message binding describes how the abstract content is mapped into a concrete format.
- WSDL has four transmission primitives that an endpoint can support:
- One-Way:endpoint receives a message.
- Request-Response:endpoint receives a message, and sends a correlated message.
- Solicit-Response :endpoint sends a message, and receives a correlated message.
- Notification : endpoint sends a message.
- There may be any number of binding for a port type. A Binding must specify exactly one protocol. Binding must not specify address information.
- A port must not specify more than one address. It must not specify any binding information other than address information.
- Ports within service have the following relationship:
- None of the ports communicate with each other (e.g. the output of one port is not the input of another).
- If a service has several ports that share a port type, but employ different bindings or addresses, the ports are alternatives. This allows a consumer of a WSDL document to choose particular port(s) to communicate with based on some criteria (protocol, distance, etc.).
- SOAP Binding extends WSDL with the following extension elements:
- soap:binding - Signify that the binding is bound to the SOAP protocol format: Envelop, header and body. URI for the transport attribute of this element signifies which transport of SOAP. Can be HTTP, SMTP, FTP etc.,
- soap:operation - Required for the HTTP protocol binding of SOAP. For other SOAP protocol bindings, soap:action attribute must not be specified and this attribute may be omitted.
- soap:body - specifies how message parts appear inside soap body element. May be abstract schema defintiions or concrete. If abstract, then serialized according to some encoding style. The soap:body element is used in both RPC-oriented and document-oriented messages, but the style of the enclosing operation has important effects on how the Body section is structured:
- If the operation style is rpc each part is a parameter or a return value and appears inside a wrapper element within the body
- If the operation style is document there are no additional wrappers, and the message parts appear directly under the SOAP Body element.
- soap:address - The SOAP address binding is used to give a port an address (a URI). The URI scheme specified for the address must correspond to the transport specified by the soap:binding.
SOAP Message Embedded in HTTP Request
POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org
/soap/envelope/">
<soapenv:Body>
<m:GetLastTradePrice xmlns:m="Some-URI">
<m:tickerSymbol>DIS</m:tickerSymbol>
</m:GetLastTradePrice>
</soapenv:Body>
</soapenv:Envelope>
SOAP Message Embedded in HTTP Response
HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org
/soap/envelope/">
<soapenv:Body>
<m:GetLastTradePriceResponse xmlns:m="Some-URI">
<m:price>34.5</m:price>
</m:GetLastTradePriceResponse>
</soapenv:Body>
</soapenv:Envelope>
Thursday, April 20, 2006
Managing state in SOA
A good link on managing state in SOA. Some of the key points:
1. To Manage conversation state, a state identifier needs to maintain following information w.r.t each request-response interaction
2. This identifier information can be passed in three ways:
* Pass the identifier information as an extra parameter in the Web service method; the Web service interface can be designed to accept not only the XML document message, but also to accept additional parameters that represent the state identifier information.
* Pass the identifier information as a part of the XML document—the XML document can contain such information embedded within its body.
* Pass the identifier information in the SOAP message header.
3. First two methods are not preferred as code becomes harder to maintain.
4. Three-step development process:
1. Design and code the basic service components.
2. Develop SOAP message handlers.
3. Construct Web services (expose) out of developed J2EE components.
5. SOAP handlers are for: to handle the insertion of state qualifiers into the standard SOAP message definition. In JAX-RPC services, a handler is represented by a handler class that implements handleRequest() and handleResponse() methods for modifying the request and response message.
6. Create Handlers implementing javax.xml.rpc.handler.Handler and implementing the handleRequest method. The javax.xml.soap.SOAPMessage class is used by the handler to manipulate the SOAP message. A SOAPMessage object contains a SOAPPart object that contains the actual SOAP XML document and a SOAPEnvelope object that is "decomposed" to access SOAP body and header.
7. Get a SoapFactory instance and createElement using it. To the element addTextNode. Finally construct WS using handlers and deploy to AS.
1. To Manage conversation state, a state identifier needs to maintain following information w.r.t each request-response interaction
- Unique identifier of the Web service client
- Identifier of the Web service conversation originated for that client
- Identifier of the service request within that conversation
- Indicator of the conversation phase between the service requester (client) and service provider (Starting, Continuing, and Ending), which is used by the service for proper state maintenance
- Indicator of the interaction status between the service distribution function of the Web services infrastructure and the invocation interface (very helpful in dynamic invocations with late-binding of Web service interfaces)
2. This identifier information can be passed in three ways:
* Pass the identifier information as an extra parameter in the Web service method; the Web service interface can be designed to accept not only the XML document message, but also to accept additional parameters that represent the state identifier information.
* Pass the identifier information as a part of the XML document—the XML document can contain such information embedded within its body.
* Pass the identifier information in the SOAP message header.
3. First two methods are not preferred as code becomes harder to maintain.
4. Three-step development process:
1. Design and code the basic service components.
2. Develop SOAP message handlers.
3. Construct Web services (expose) out of developed J2EE components.
5. SOAP handlers are for: to handle the insertion of state qualifiers into the standard SOAP message definition. In JAX-RPC services, a handler is represented by a handler class that implements handleRequest() and handleResponse() methods for modifying the request and response message.
6. Create Handlers implementing javax.xml.rpc.handler.Handler and implementing the handleRequest method. The javax.xml.soap.SOAPMessage class is used by the handler to manipulate the SOAP message. A SOAPMessage object contains a SOAPPart object that contains the actual SOAP XML document and a SOAPEnvelope object that is "decomposed" to access SOAP body and header.
7. Get a SoapFactory instance and createElement using it. To the element addTextNode. Finally construct WS using handlers and deploy to AS.
Subscribe to:
Posts (Atom)