Java Restful Web Services (一)
REST(Representational State Transfer,表述性狀態轉移),是Roy
Thomas Fielding在他2000年的博士論文《Architectural
Styles and the Design of Network-based Software Architectures》提出,與複雜的SOAP和XML-RPC相比,REST更加簡潔,越來越多的Web服務開始採用REST風格設計和實現。Rest是一種架構風格,在這樣的架構風格中,物件被抽象成為一種資源,資源的命名使用概念清晰的名詞來定義,HTTP+URI+XML是Rest的基本實現形式。JAX-RS是JAVA
EE6 引入的一個新技術,是Java領域的Rest式的Web服務的標準規範,JAX-RS即Java API for RESTful Web Services,是一個Java 程式語言的
基於Jersey開發Restful服務,新建一個Web工程,引入我們需要的jar包,Jersey最新參考實現Jar包可通過Jersey官方網站下載。
新建一個package,定義資源類。
package cn.com.abc.rest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; @Path("helloworld") public class HelloWorldResource { public static final String CLICHED_MESSAGE = "Hello World!"; @GET @Path("/before") @Produces("text/plain") public String getHelloBefore() { return "hello before"; } @GET @Produces("text/plain") public String getHello() { return CLICHED_MESSAGE; } @GET @Path("/{param}") @Produces("text/plain") public String getHello(@PathParam("param") String username) { return "Hello Path Param " + username; } @GET @Path("/user") @Produces("text/plain") public String getHelloWithQuery(@QueryParam("param") String username) { return "Hello Query Param " + username; } }
修改web.xml
<servlet> <servlet-name>Way REST Service</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>cn.com.abc.rest;com.fasterxml.jackson.jaxrs.json</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Way REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>
如果您的資源實現類放在不同的包中,那麼您可在屬性param-value中指定多個包名用以對外公佈REST服務介面。接下來是我們的測試類。
package cn.com.abc.test;
import static org.junit.Assert.*;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class HelloWorldResourceTest {
private WebTarget target;
public static final String BASE_URI = "http://localhost:8090/NoteMail/rest/";
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("setUpBeforeClass");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("tearDownAfterClass");
}
@Before
public void setUp() throws Exception {
System.out.println("setUp");
Client c = ClientBuilder.newClient();
target = c.target(BASE_URI);
System.out.println(target.getUri());
}
@After
public void tearDown() throws Exception {
System.out.println("tearDown");
}
@Test
public void testGetHello() {
String responseMsg = target.path("helloworld").request()
.get(String.class);
assertEquals("Hello World!", responseMsg);
}
@Test
public void testGetHelloWithPathParam() {
String responseMsg = target.path("helloworld/ABC").request().get(String.class);
assertEquals("Hello Path Param ABC", responseMsg);
}
@Test
public void testGetHelloWithQueryParam() {
String responseMsg = target.path("helloworld/user").queryParam("param", "ABC").request().get(String.class);
assertEquals("Hello Query Param ABC", responseMsg);
}
@Test
public void testGetHelloBefore() {
String responseMsg = target.path("helloworld/before/").request()
.get(String.class);
assertEquals("hello before", responseMsg);
}
}
在資源實現類中包含了兩個不同註解的方法@PathParam和@QueryParam,兩種不同的方法呼叫方式也略有不同。各種不同的註解使用將在下一篇中介紹。
對於@PathParam,其呼叫方式為:
http://localhost:8090/NoteMail/rest/helloworld/ABC
對於@QueryParam,其呼叫方式為
http://localhost:8090/NoteMail/rest/helloworld/user?param=ABC
我們通過訪問“服務根路徑/application.wadl”(本示例為http://localhost:8090/NoteMail/rest/application.wadl)可以看到當前REST環境中所提供的REST伺服器介面,WADL(Web Application Description Language)是用來描述基於HTTP的Rest式Web服務部署情況。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
<doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 2.15 2015-01-12 22:32:50"/>
<doc xmlns:jersey="http://jersey.java.net/" jersey:hint="This is simplified WADL with user and core resources only. To get full WADL with extended resources use the query parameter detail. Link: http://localhost:8090/NoteMail/rest/application.wadl?detail=true"/>
<grammars/>
<resources base="http://localhost:8090/NoteMail/rest/">
<resource path="helloworld">
<method id="getHello" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
<resource path="/before">
<method id="getHelloBefore" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
<resource path="/user">
<method id="getHelloWithQuery" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="param" style="query" type="xs:string"/>
</request>
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
<resource path="/{param}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="param" style="template" type="xs:string"/>
<method id="getHello" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
</resource>
<resource path="books">
<method id="saveBook" name="POST">
<request>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
</request>
<response>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
</response>
</method>
<method id="getBooks" name="GET">
<response>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
</response>
</method>
<resource path="{bookid:[0-9]*}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="bookid" style="template" type="xs:int"/>
<method id="updateBook" name="PUT">
<request>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
<representation mediaType="text/xml"/>
</request>
<response>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
</response>
</method>
<method id="deleteBook" name="DELETE">
<response>
<representation mediaType="*/*"/>
</response>
</method>
<method id="getBookByPath" name="GET">
<response>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
</response>
</method>
</resource>
<resource path="/book">
<method id="getBookByParam" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="bookid" style="query" type="xs:int"/>
</request>
<response>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
</response>
</method>
</resource>
<resource path="/booktest">
<method id="sayHello" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
</resource>
<resource path="users">
<resource path="/{username}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="username" style="template" type="xs:string"/>
<method id="getUserIgnore" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
<resource path="/{username: [a-zA-Z][a-zA-Z_0-9]*}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="username" style="template" type="xs:string"/>
<method id="getUser" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
</resource>
<resource path="/hellorestanother">
<method id="sayHello" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
<resource path="/{param}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="param" style="template" type="xs:string"/>
<method id="sayHelloToUTF8" name="GET">
<response>
<representation mediaType="text/plain; charset=UTF-8"/>
</response>
</method>
</resource>
</resource>
<resource path="/hellorest">
<method id="sayHello" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
<resource path="/{param}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="param" style="template" type="xs:string"/>
<method id="sayHelloToUTF8" name="GET">
<response>
<representation mediaType="text/plain; charset=UTF-8"/>
</response>
</method>
</resource>
</resource>
<resource path="/mail">
<method id="mailREST" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="server" style="query" type="xs:string"/>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="username" style="query" type="xs:string"/>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="password" style="query" type="xs:string"/>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="dbname" style="query" type="xs:string"/>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="subject" style="query" type="xs:string"/>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="sendto" style="query" type="xs:string"/>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="content" style="query" type="xs:string"/>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="ishtml" style="query" type="xs:string"/>
</request>
<response>
<representation mediaType="text/plain; charset=UTF-8"/>
</response>
</method>
<resource path="/sendService">
<method id="crunchifyREST" name="POST">
<request>
<representation mediaType="application/json"/>
</request>
<response>
<representation mediaType="text/plain; charset=UTF-8"/>
</response>
</method>
</resource>
</resource>
<resource path="device">
<method id="get" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="ip" style="query" type="xs:string"/>
</request>
<response>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
</response>
</method>
<method id="put" name="PUT">
<response>
<representation mediaType="application/xml"/>
<representation mediaType="application/json"/>
</response>
</method>
</resource>
<resource path="UserInfoService">
<resource path="/name/{i}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="i" style="template" type="xs:string"/>
<method id="userName" name="GET">
<response>
<representation mediaType="text/xml"/>
</response>
</method>
</resource>
<resource path="/age/{j}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="j" style="template" type="xs:int"/>
<method id="userAge" name="GET">
<response>
<representation mediaType="text/xml"/>
</response>
</method>
</resource>
</resource>
</resources>
</application>