Jax-rs Way of RESTful Web Service Development
--based on the implementation of Cxf+spring
Web Service currently has two categories in style, one based on the SOAP protocol and one that is fully compliant with the HTTP protocol. The SOAP-style Web service is already mature and widely used, and has become the industry standard for Web service. But RESTful Web Service is gaining momentum, especially with its flexibility and the perfect combination of Ajax, and it's worth knowing. RESTful is an architectural style that is fully compliant with the HTTP protocol. It's like people have gone through an endless way of returning to HTTP extensions and expansions, letting Web service developers back into the HTTP protocol. The RESTful Advocate uses the HTTP protocol verb and the actual data operation's add and delete to change the correspondence, like the HTTP PUT, GET, POST, delete respectively corresponding the data in the Web system changes, checks, increases, deletes the operation. Of course, RESTful support HTTP verb is not limited to the above 4, there are other head,option like ... And so on, but the above 4 is enough for our daily use.
There are many frameworks for Web service at the moment, but I've only used CXF, so I'll take apache-cxf2.2.2 as an example to introduce the development of RESTful Web service.
There are jax-rs styles, Provider, Servlets, Httpbinding, and maybe other ways to publish a more common RESTful Web Service, but that's all I know. The overall feeling of the most lazy way is to use the servlet way to publish the Web service, that is, the Web Service release, is actually the transformation of the servlet understanding, the servlet itself supports the various actions in the HTTP request support, so the servlet Native is a RESTful Web Service. But this way I think it's not fashionable. Povider Way I understand, need to implement Provider interface, feel very constrained. When I lost interest in RESTful, I found the jax-rs style, jax-rs like a pure MM, the server configuration is complete, and the configuration is very delicate. But also very approachable, the client invocation is very flexible. Then I'll introduce her to you.
1. Environment Construction
In this example, using Web project, the process of building a Web project is no longer exhaustive, just a list of the jar packages required by the environment. As follows:
Here is the jar in my local project, for reference only.
Note: Jsr311-api-1.0.jar is essential if you want to return the JSON data format directly in a RESTful service.
2. Service Development
We introduce a simple example of a customer information service. Service implementation of the business people do not care too much, focus on the process of service development is good.
2.1 straight to
First we construct a customer's VO first.
Java code
- Package com.harvey.cxf.demo.rest.rs.vo;
- Import Javax.xml.bind.annotation.XmlAccessType;
- Import Javax.xml.bind.annotation.XmlAccessorType;
- Import javax.xml.bind.annotation.XmlRootElement;
- @XmlRootElement (name = "Customer")
- @XmlAccessorType (Xmlaccesstype.field)
- public class Customer {
- Private long ID;
- private String name;
- Public long getId () {
- return ID;
- }
- public void SetId (long id) {
- This.id = ID;
- }
- Public String GetName () {
- return name;
- }
- public void SetName (String name) {
- THIS.name = name;
- }
- }
Next, take customerservice as the implementation class for customer service
For example, the most common query for a customer's information is as follows:
Java code
- @Path ("/")
- public class CustomerService {
- ......
- Normal Path parameter mode GET request
- @GET
- @Path ("/customers/{id}")
- Public Customer GetCustomer (@PathParam ("id") String ID) {
- ......
- }
- }
Assuming that our service is eventually published at Http://127.0.0.1:8080/customerservice, we only need to send a GET request if we want to query a customer's information http://127.0.0.1:8080/ customerservice/customers/123, or simply enter the URL directly into the browser to access the service directly. Where the 123 passed in the URL is automatically adapted to the {id} parameter in the service. Such a simple RESTful Web service that handles GET requests has been developed.
2.2 parameter Handling
In the example above, we see that the client passes the parameters in the service request by the way the request path is passed in. As in previous http://127.0.0.1:8080/customerservice/customers/123, customer ID123 as part of the path. The corresponding server-side parameter configuration takes a @PathParam ("id") String ID.
In addition to supporting path passing, we can also specify in the query parameters of the request. For example, or to query a customer's information, the server-side code can be as follows:
Java code
- ......
- @GET
- @Path ("/customers/getcustomerbyid")
- Public Customer getcustomerbyquerystring (@QueryParam ("id") String ID) {
- ......
- }
At this point the service access URL is:
Http://127.0.0.1:8080/customerservice/customers/getCustomerById?id=123
Speaking of which, there may be an audience to ask (perhaps no one asked): The previous mentioned are simple parameters, this is easy, then for some complex bean parameters how to deal with it?
That's a good question, so let me give you an example. Say the example before repeating it, look at the example of the code should not be entangled in the business logic, only look at the technical implementation of the way.
Java code
- ......
- @GET
- @Path ("/customers/getcust")
- Public Customer GetCustomer (@QueryParam ("") Customer Cust) {
- ......
- }
In this example, you need to pass in a previously declared customer information class as a parameter. Parameter processing is Queryparam, so this time we access URL format similar to the following:
Http://127.0.0.1:8080/customerservice/customers/getCust?id=123&name=xiaoming
If the parameter bean also includes other properties, it is good to append the & symbol in turn. There is no difference in the usual Web access.
If you think that the way to query string is not enough personality, you can use another: @MatrixParam
The server-side code is as follows:
Java code
- ......
- @GET
- @Path ("/customers/getcustbymat")
- Public Customer Getcustomerbymat (@MatrixParam ("") Customer Cust) {
- ......
- }
In this case, we can use the following form when we visit again:
Http://127.0.0.1:8080/customerservice/customers/getCustByMat;id=123;name=xiaoming
If the Cusmomer has other properties, it can be appended directly to the following parameters; Separated.
The parameters we use above are different in the way they are treated, but they are annotated. The next appearance of this is a special character. Please welcome the body parameters ...
Java code
- ......
- @POST
- @Path ("/addcustomer")
- Public Customer Addcustomer (String body) {
- ......
- }
This body parameter is special in Jax-rs, which does not precede any annotations, it represents the body content of the request or the InputStream of the request, and automatically resolves the map to a string parameter. Because our example is a GET request before, the message is not body, so the attentive listener may find our verb configuration of this service in order to @POST.
2.3 request, answer data format
In the previous example, our method returned the customer, but our system is a RESTful Web service Ah, the client received is definitely an HTTP response message, then the return of the customer what is a message content?
By default, the Customer of the reponse message is returned in XML format. Similar to:
<Customer><id>123</id><name>skdjl</name></Customer>
The client invokes the server-side service, obtains the result of the preceding XML string, and then carries out subsequent processing.
Since this is said by default, the implication is that there are a lot of other things, but it needs to be configured. I have to say @produces annotation. @Produces is the type of data format that is returned by the server side, including Application/xml, Application/json, Application/text ..., is actually the type in the content-type of our common web-side. If we set to Application/json, the data format returned naturally is in JSON form. Another note: @Consumes, which corresponds to the @produces. @Consumes is the format of the requested data sent by the client, which corresponds to the same type of support as @produces. The specific configuration is as follows:
Java code
- ......
- @POST
- @Path ("/addcustomerusebean")
- @Produces ("Application/json")
- @Consumes ("Application/xml")
- Public Customer Addcustomerusebean (Customer Cust) {
- ......
- }
This example means that the client passes in the Customer as a parameter, the format is XML-style, and the server-side answers the data in JSON style. Of course, we can also add @Produces and @Consumes as the overall request and response style of the service, if the specific service method is not set, the @Produces and @Consumes settings of the class are used.
3 Service Configuration
After service development is complete, all we have to do is publish the service. The release method is also flexible and can be encoded in a way that can be configured in conjunction with spring. In the following example we use the latter. Configuration of the content no longer do too much explanation, you can see to understand.
3.1 Web the configuration
XML code
- <?xml version= "1.0" encoding= "UTF-8"?>
- <web-app version= "2.4"
- Xmlns= "HTTP://JAVA.SUN.COM/XML/NS/J2EE"
- 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/web-app_2_4.xsd ">
- <display-name>DEMO</display-name>
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:/applicationContext*.xml</param-value>
- </context-param>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <listener>
- <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
- </listener>
- <servlet>
- <servlet-name>CXFServlet</servlet-name>
- <servlet-class>
- Org.apache.cxf.transport.servlet.CXFServlet
- </servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>CXFServlet</servlet-name>
- <url-pattern>/services/*</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
3.2 Spring configuration file
XML code
- <?xml version= "1.0" encoding= "UTF-8"?>
- <beans
- Xmlns= "Http://www.springframework.org/schema/beans"
- Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"
- xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP"
- xmlns:cxf= "Http://cxf.apache.org/core"
- Xmlns:jaxws= "Http://cxf.apache.org/jaxws"
- Xmlns:jaxrs= "Http://cxf.apache.org/jaxrs"
- Xsi:schemalocation= "
- Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- Http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
- Http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
- HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/spring-aop.xsd ">
- <import resource= "Classpath:meta-inf/cxf/cxf.xml"/>
- <import resource= "Classpath:meta-inf/cxf/cxf-extension-soap.xml"/>
- <import resource= "Classpath:meta-inf/cxf/cxf-servlet.xml"/>
- <import resource= "Classpath:meta-inf/cxf/cxf-extension-jaxrs-binding.xml"/>
- <jaxrs:server id= "CustomerService" address= "/customerservice" >
- <jaxrs:serviceBeans>
- <ref bean= "Customerservicebean"/>
- </jaxrs:serviceBeans>
- </jaxrs:server>
- <bean id= "Customerservicebean" class= "Com.harvey.cxf.demo.rest.rs.server.CustomerService"/>
- </beans>
Then start our web application and the service is released. can be typed in the browser:
HTTP://127.0.0.1:8080/CUSTOMERSERVICE/CUSTOMERS/1 test the service is normal.
From the above example you may find that although we are doing restful examples, many of the services provided by the verb are composed of action components such as Getcustomer,addcustomer and so on, The existence of these words indicates that our services, while using restful technology, do not follow the concept of the ROA (resource-oriented architecture), and true Roa believers may be very uncomfortable seeing the example above. Because after all, restful and Roa are childhood. But as mentioned earlier, it's good to focus on technology implementations.
4 Client Calls
Our Service release is complete, and we can do a test client program next. For RESTful call way a lot, can use Java Connect Way, also can use Apche of httpclint, also can use CXF provide WebClient, and so on. In the following client code, there are several methods of invocation, where we do not have to rigidly, can arbitrarily choose their own familiar way. The code is described in section 5th.
Jax-rs Way of RESTful Web Service Development