Release restful web service with JAX-WS

Source: Internet
Author: User
Tags java se
Both the ea3 version of The JAX-WS or the JAX-WS published with jwsdp 2.0 supports publishing and using restful Web Services. The following example shows how to publish a restful web service with a JAX-WS.

To release restful web service with a JAX-WS, you must first create an implementation of the javax. xml. ws. provider <t> interface. The provider interface is another dynamic implementation method for the standard Terminal Implementation class. It is similar to javax. xml. ws. The dispatch interface is used on the client. You will notice that provider <t> is a generated class. It supports provider <javax. XML. transform. source> and provider <javax. XML. soap. soapmessage>, or support provider <javax. activation. datasource> and provider <javax. XML. transform. source>. When creating the provider implementation, you can choose the form of request and response messages to be processed.

The example web service we want to create is very simple. It adds two numbers and returns the result. In the provider implementation, we use provider <source> and XML/HTTP binding. First, we write an implementation of addnumbers provider to declare the addnumbers class.

Public class addnumbersimpl implements provider
{}

Next, declare the @ resource tag, which is used to inject webservicecontext into our addnumbersimpl instance when the JAX-WS is running.

Public class addnumbersimpl implements provider {
@ Resource
Protected webservicecontext wscontext;
}

The next step is to implement the T provider. Invoke (T request) method. First, we should write the following method declaration, which is a simple try-Catch Block to handle exceptions. Note: This method takes a source object as the request and returns a source object as the response. This is consistent with the provider type we created.

Public class addnumbersimpl implements provider {
@ Resource
Protected webservicecontext wscontext;

Public source invoke (Source request ){
Try {

} Catch (exception e ){
E. printstacktrace ();
Throw new httpexception (500 );
}
}
}

In this example, the addnumbers Web Service extracts the numbers to be added from the URL path or HTTP request to obtain the request. The request string and path string can be obtained from messagecontext and webservicecontext wscontext. It will be injected into our addnumbers object. The following code is used to obtain path_info from the URL and check whether it is in a proper format.

String Path = (string) MC. Get (messagecontext. path_info );
If (path! = NULL & path. Contains ("/num1 ")&&
Path. Contains ("/num2 ")){
Return createresultsource (PATH );
}

The createresultsource (string Str) method only creates the source object from the properly formatted messagecontext. path_info string. It extracts the numbers to be added from the path, adds them, and calls the createresultsource (INT sum) method. The source code of these two methods is as follows:

Private source createresultsource (string Str ){
Stringtokenizer ST = new stringtokenizer (STR, "= &/");
String token = ST. nexttoken ();
Int number1 = integer. parseint (St. nexttoken ());
St. nexttoken ();
Int number2 = integer. parseint (St. nexttoken ());
Int sum = number1 + number2;
Return createresultsource (SUM );
}

Private source createresultsource (INT sum ){
String body =
"<Ns: addnumbersresponse xmlns: NS =/" http://duke.org/"> <ns: Return>"
+ Sum
+ "</Ns: Return> </ns: addnumbersresponse> ";
Source source = new streamsource (
New bytearrayinputstream (body. getbytes ()));
Return source;
}

Therefore, the invoke method in our example will look like the following.

Public source invoke (source ){
Try {
Messagecontext MC = wscontext. getmessagecontext ();
// Check for a path_info request
String Path = (string) MC. Get (messagecontext. path_info );
If (path! = NULL & path. Contains ("/num1 ")&&
Path. Contains ("/num2 ")){
Return createresultsource (PATH );
}
Throw new httpexception (404 );
} Catch (exception e ){
E. printstacktrace ();
Throw new httpexception (500 );
}
}

If messagecontext. path_info is not found, an httpexception (404) exception is thrown in this example. Our example terminal does not throw this exception, but checks the request string for the method parameters. For example, messagecontext. path_info. The request string can be obtained from messagecontext using the following code.

String query = (string) MC. Get (messagecontext. QUERY_STRING );

Therefore, we can pass the request string to the createresultsource (string Str) method to parse the parameter. to deploy a servlet container for our example, we can also use the standard servletrequest object to extract the request string. To deploy a Java SE-based terminal, we must use messagecontext. QUERY_STRING.

The following code obtains the values of num1 and num2, and then calls the createresultsource (INT sum) method to create the source object. It will be returned from the invoke method.

Servletrequest Req = (servletrequest) MC. Get (messagecontext. servlet_request );
Int num1 = integer. parseint (req. getparameter ("num1 "));
Int num2 = integer. parseint (req. getparameter ("num2 "));
Return createresultsource (num1 + num2 );

So far, our addnumbers class should be as follows:

Public class addnumbersimpl implements provider {

@ Resource
Protected webservicecontext wscontext;

Public source invoke (source ){
Try {
Messagecontext MC = wscontext. getmessagecontext ();
// Check for a path_info request
String Path = (string) MC. Get (messagecontext. path_info );
If (path! = NULL & path. Contains ("/num1 ")&&
Path. Contains ("/num2 ")){
Return createresultsource (PATH );
}
String query = (string) MC. Get (messagecontext. QUERY_STRING );
System. Out. println ("query string =" + query );
Servletrequest Req = (servletrequest) MC. Get (messagecontext. servlet_request );
Int num1 = integer. parseint (req. getparameter ("num1 "));
Int num2 = integer. parseint (req. getparameter ("num2 "));
Return createresultsource (num1 + num2 );
} Catch (exception e ){
E. printstacktrace ();
Throw new httpexception (500 );
}
}

Private source createresultsource (string Str ){
Stringtokenizer ST = new stringtokenizer (STR, "= &/");
String token = ST. nexttoken ();
Int number1 = integer. parseint (St. nexttoken ());
St. nexttoken ();
Int number2 = integer. parseint (St. nexttoken ());
Int sum = number1 + number2;
Return createresultsource (SUM );
}

Private source createresultsource (INT sum ){
String body =
"<Ns: addnumbersresponse xmlns: NS =/" http://duke.org/"> <ns: Return>"
+ Sum
+ "</Ns: Return> </ns: addnumbersresponse> ";
Source source = new streamsource (
New bytearrayinputstream (body. getbytes ()));
Return source;
}
}

To complete addnumbers, We need to declare some markup to demonstrate how to use this class during JAX-WS runtime. @ Webserviceprovider indicates that this class is a provider-based terminal rather than a service Terminal Implementation class that needs to be specified by @ WebService. The last tag we need to add is @ bindingtype (value = httpbinding. http_binding ). This tag indicates that the addnumbers terminal will be bound with httpbinding. http_binding instead of soapbinding. soap11http_binding or soapbinding. soap12http_binding. The code for the final class is as follows:

@ Webserviceprovider
@ Bindingtype (value = httpbinding. http_binding)
Public class addnumbersimpl implements provider {

@ Resource
Protected webservicecontext wscontext;

Public source invoke (source ){
Try {
Messagecontext MC = wscontext. getmessagecontext ();
// Check for a path_info request
String Path = (string) MC. Get (messagecontext. path_info );
If (path! = NULL & path. Contains ("/num1 ")&&
Path. Contains ("/num2 ")){
Return createresultsource (PATH );
}
String query = (string) MC. Get (messagecontext. QUERY_STRING );
System. Out. println ("query string =" + query );
Servletrequest Req = (servletrequest) MC. Get (messagecontext. servlet_request );
Int num1 = integer. parseint (req. getparameter ("num1 "));
Int num2 = integer. parseint (req. getparameter ("num2 "));
Return createresultsource (num1 + num2 );
} Catch (exception e ){
E. printstacktrace ();
Throw new httpexception (500 );
}
}

Private source createresultsource (string Str ){
Stringtokenizer ST = new stringtokenizer (STR, "= &/");
String token = ST. nexttoken ();
Int number1 = integer. parseint (St. nexttoken ());
St. nexttoken ();
Int number2 = integer. parseint (St. nexttoken ());
Int sum = number1 + number2;
Return createresultsource (SUM );
}

Private source createresultsource (INT sum ){
String body =
"<Ns: addnumbersresponse xmlns: NS =/" http://duke.org/"> <ns: Return>"
+ Sum
+ "</Ns: Return> </ns: addnumbersresponse> ";
Source source = new streamsource (
New bytearrayinputstream (body. getbytes ()));
Return source;
}
}

To deploy our terminal on a servlet container that runs the JAX-WS Ri, we need to create a war file. For example, we name the war file as a jaxws-restful.war. This file requires a very simple web. xml file to configure the JAX-WS Ri servlet. The Code is as follows:

<Web-app version = "2.4" xmlns = "http://java.sun.com/xml/ns/j2ee">
<Listener>
<Listener-class> com. Sun. xml. ws. Transport. http. servlet. wsservletcontextlistener
</Listener>
<Servlet>
<Servlet-Name> restful-addnumbers </servlet-Name>
<Servlet-class> com. Sun. xml. ws. Transport. http. servlet. wsservlet
<Load-on-startup> 1 </load-on-startup>
</Servlet>
<Servlet-mapping>
<Servlet-Name> restful-addnumbers </servlet-Name>
<URL-pattern>/addnumbers/* </url-pattern>
</Servlet-mapping>
<Session-config>
<Session-Timeout> 60 </session-Timeout>
</Session-config>
</Web-app>

Next, we add a sun-jaxws.xml deployment descriptor to the war file. The following is an example:

<Endpoints
Xmlns = "http://java.sun.com/xml/ns/jax-ws/ri/runtime"
Version = "2.0">

<Endpoint
Name = "restful-addnumbers"
Implementation = "Restful. server. addnumbersimpl"
WSDL = "WEB-INF/WSDL/addnumbers. WSDL"
URL-pattern = "/addnumbers/*"/>
</Endpoints>

You will notice that. XML and sun-jaxws.xml have the <URL-pattern>/addnumbers/* </url-pattern> element and URL-pattern = "/addnumbers/*" attribute, therefore, we can match any additional parameters in the path. (For example,.../num1/10/num2/20)

You will also notice a specified WSDL file from the sun-jaxws.xml deployment descriptor. It is important to tell the JAX-WS Ri not to generate a WSDL for the terminal. The following is a simple description of addnumbers. WSDL.

<? XML version = "1.0" encoding = "UTF-8"?>
<Definitions>
</Definitions>

Once the addnumbers terminal is deployed, you can enter the following URL in your browser to test it. (It may be a little different depending on your configuration)

HTTP: /localhost: 8080/jaxws-restful/addnumbers/num1/10/num2/20
Shocould return the following:
<Ns: addnumbersresponse xmlns: NS = "http://duke.org">
<Ns: Return> 30 </ns: Return>
</Ns: addnumbersresponse>

Http: // localhost: 8080/jaxws-restful/addnumbers? Num1 = 10 & num2 = 50
Shocould return the following:
<Ns: addnumbersresponse xmlns: NS = "http://duke.org">
<Ns: Return> 60 </ns: Return>
</Ns: addnumbersresponse>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.