Download JAX-RPC - Andrew.cmu.edu

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

URL redirection wikipedia , lookup

Transcript
JAX-RPC
The Java API for XML Remote
Procedure Calls
Notes from The J2EE Tutorial 1.4 From
Sun Microsystems
JAX-RPC Notes
• Based on W3C
Technologies
• SOAP
• WSDL
• HTTP
• Java types are
mapped to
XML/WSDL
• String to xsd:string
• BigDecimal[]
and more…
• Primitive types
JAX-RPC Server Side
The service
endpoint
interface
package helloservice;
import java.rmi.Remote;
Import java.rmi.RemoteException;
public interface HelloIF extends Remote {
public String sayHello(String s) throws
RemoteException;
}
Implement the service
package helloservice;
public class HelloImpl implements HelloIF {
public String message ="Hello";
public String sayHello(String s) {
return message + s;
}
}
Provide a config-interface.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration
xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<service
name="MyHelloService"
targetNamespace="urn:Foo"
typeNamespace="urn:Foo"
packageName="helloservice">
<interface name="helloservice.HelloIF"/>
</service>
</configuration>
Three steps to build
1. compile-service
2. generate-wsdl
3. generate-mapping from service classes
package names to namespace URI’s in
the WSDL and create ties (skeletons)
J2EE1.4 provides an ant task to perform all
three steps
Behind the Scenes
• The JAX-RPC web service is actually a
servlet and placed in the web tier
On the client side
We’ll examine four options
1.
2.
3.
4.
Static stubs
compiled by wscompile before runtime
Dynamic stubs
has an interface but fetches the WSDL at runtime
Dynamic Invocation Interface
knows no interface - the method names
and signatures
A J2EE Application Client
Locate the local web service with JNDI
Client Using a Static Stub
import javax.xml.rpc.Stub;
It almost looks like a local call.
public class HelloClient {
private String endpointAddress;
public static void main(String[] args) {
System.out.println("Endpoint address = " + args[0]);
try {
Stub stub = createProxy();
stub._setProperty
(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY
args[0]);
// cast the stub to the proper interface
HelloIF hello = (HelloIF)stub;
// call the methods defined there
System.out.println(hello.sayHello("Duke!"));
}
catch (Exception ex) {
ex.printStackTrace();
}
}
private static Stub createProxy() {
// MyHelloService_Impl is created by wscompile
return
(Stub) (new MyHelloService_Impl().getHelloIFPort());
}
}
Using a Dynamic Stub
public class HelloClient {
// We have more work to do
public static void main(String[] args) {
try {
String UrlString = args[0] + "?WSDL";
String nameSpaceUri = "urn:Foo";
String serviceName = "MyHelloService";
String portName = "HelloIFPort";
System.out.println("UrlString = " + UrlString);
URL helloWsdlUrl = new URL(UrlString);
ServiceFactory serviceFactory =
ServiceFactory.newInstance();
Service helloService =
serviceFactory.createService(helloWsdlUrl,
new QName(nameSpaceUri, serviceName));
WSDL is fetched at runtime
dynamicproxy.HelloIF myProxy =
(dynamicproxy.HelloIF)
helloService.getPort(
new QName(nameSpaceUri, portName),
dynamicproxy.HelloIF.class);
System.out.println(myProxy.sayHello("Buzz"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Client Using a Dynamic Invocation
Interface
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.ParameterMode;
public class HelloClient {
private static String qnameService = "MyHelloService";
private static String qnamePort = "HelloIF";
private static String BODY_NAMESPACE_VALUE =
"urn:Foo";
private static String ENCODING_STYLE_PROPERTY =
"javax.xml.rpc.encodingstyle.namespace.uri";
private static String NS_XSD =
"http://www.w3.org/2001/XMLSchema";
private static String URI_ENCODING =
"http://schemas.xmlsoap.org/soap/encoding/";
public static void main(String[] args) {
System.out.println("Endpoint address = " + args[0]);
try {
ServiceFactory factory =
ServiceFactory.newInstance();
Service service =
factory.createService(
new QName(qnameService));
“MyHelloService”
HelloIF
QName port = new QName(qnamePort);
The URL and service names are all
specified at runtime
Who we
Call call = service.createCall(port);
are calling and
call.setTargetEndpointAddress(args[0]);
how is
determined at
call.setProperty(Call.SOAPACTION_USE_PROPERTY, runtime
new Boolean(true));
call.setProperty(Call.SOAPACTION_URI_PROPERTY
"");
call.setProperty(ENCODING_STYLE_PROPERTY,
URI_ENCODING);
QName QNAME_TYPE_STRING =
new QName(NS_XSD, "string");
SOAP
call.setReturnType(QNAME_TYPE_STRING);
details must
be specified
Very carefully prepare the call.
call.setOperationName(
new QName(BODY_NAMESPACE_VALUE,"sayHello"));
call.addParameter("String_1", QNAME_TYPE_STRING,
ParameterMode.IN);
String[] params = { "Murph!" };
String result = (String)call.invoke(params);
System.out.println(result);
Make the call
} catch (Exception ex) {
Get the result
ex.printStackTrace();
}
}
}
Harder to program but allows
for a great deal of flexibility.
There is a lot less hard coding
going on here. A lot of this could
be chosen by a sophisticated user
at runtime
J2EE Application Client
import javax.xml.rpc.Stub;
import javax.naming.*;
public class HelloClient {
private String endpointAddress;
public static void main(String[] args) {
System.out.println("Endpoint address = " + args[0]);
try {
Context ic = new InitialContext();
MyHelloService myHelloService = (MyHelloService)
ic.lookup("java:comp/env/service/MyJAXRPCHello");
Ask JNDI for a
reference to a
stub for the object
HelloIF helloPort = myHelloService.getHelloIFPort();
((Stub)helloPort)._setProperty
(Stub.ENDPOINT_ADDRESS_PROPERTY,args[0]);
System.out.println(helloPort.sayHello("Jake!"));
System.exit(0);
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}
From The J2EE Tutorial
From The J2EE Tutorial
The Web Service as an EJB
• A Web service client can access J2EE
applications in two ways.
• First, the client can access a Web service
created with JAX-RPC. Behind the scenes, JAXRPC uses a servlet to implement the Web
service.
• Second, a Web service client can access a
stateless session bean through the service
endpoint interface of the bean. Other types of
enterprise beans cannot be accessed by Web
service clients.
A Stateless Session Bean as a
Web Service
• The client need not know that its
interacting with a Java EJB
• It calls the bean like it calls any other web
service
The Web Service Endpoint
Interface
The client cannot
see that it’s interacting
with an EJB
package helloservice;
import java.rmi.RemoteException;
import java.rmi.Remote;
public interface HelloIF extends Remote {
public String sayHello(String name)
throws RemoteException;
}
The Web Service Session Bean
package helloservice;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
If we added remote and home
Interfaces then this bean could
also be called using in the traditional
manner – with remote references.
No change to the bean would be
necessary.
public class HelloServiceBean implements SessionBean {
public String sayHello(String name) {
return "Hello " + name + "from HelloServiceEJB";
}
public HelloServiceBean() {}
WSDL can be generated and all
public void ejbCreate() {}
of the previous clients will work.
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}