您好,登錄后才能下訂單哦!
小編這次要給大家分享的是詳解JAVA中Jersey框架,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
Java Jersey的詳情概述
Jersey是一個RESTFUL請求服務(wù)JAVA框架,與常規(guī)的JAVA編程使用的struts框架類似,它主要用于處理業(yè)務(wù)邏輯層。
與springmvc 的區(qū)別:
1. jersey同樣提供DI,是由glassfish hk2實現(xiàn),也就是說,如果想單獨使用jersey一套,需要另外學(xué)習(xí)Bean容器;
2. MVC出發(fā)點即是WEB,但jersey出發(fā)點確實RESTFull,體現(xiàn)點在與接口的設(shè)計方面,
如MVC返回復(fù)雜結(jié)構(gòu)需要使用ModelAndView,而jersey僅僅需要返回一個流或者文件句柄;
3. jersey提供一種子資源的概念,這也是RESTFull中提倡所有url都是資源;
4. jersey直接提供application.wadl資源url說明;
5. MVC提供Session等狀態(tài)管理,jersey沒有,這個源自RESTFull設(shè)計無狀態(tài)化;
6. Response方法支持更好返回結(jié)果,方便的返回Status,包括200,303,401,403;
7. 提供超級特別方便的方式訪問RESTFull;
jersey
1.X的版本是sun公司提供的獨立的jar包,在2.X版本中,已經(jīng)將jersey融合到JavaSE中,在javax.ws.rs.*包中。
與Struts類似,它同樣可以和hibernate,spring框架整合。
由于Struts2+hibernate+spring整合在市場的占有率太高,所以很少一部分人去關(guān)注Jersey。
所以網(wǎng)上有關(guān)于Jersey的介紹很少。但是它確實是一個非常不錯的框架。對于請求式服務(wù),對于GET,DELETE請求,你甚至只需要給出一個URI即可完成操作。
舉個簡單的例子:如果你想獲得服務(wù)器數(shù)據(jù)庫中的所有數(shù)據(jù);
那么你可以在瀏覽器或者利用Ajax的GET方法,將路徑設(shè)置好;
例如:localhost:8080/Student(項目名稱)/studentinfo(項目服務(wù)總體前綴)/student(處理student對象的簽注)/getStudentInfo(最后前綴)。
你可以選擇GET獲取的數(shù)據(jù)的返回類型:JSON,XML,TEXT_HTML(String)..獲取之后,你可以通過JS將這些數(shù)據(jù)塞到html或者jsp頁面上。
Jersey是JAX-RS(JSR311)開源參考實現(xiàn)用于構(gòu)建 RESTful Web service,它包含三個部分:
核心服務(wù)器(Core Server) :通過提供JSR 311中標(biāo)準(zhǔn)化的注釋和API標(biāo)準(zhǔn)化,可以用直觀的方式開發(fā)RESTful Web服務(wù)。
核心客戶端(Core Client) :Jersey客戶端API能夠幫助開發(fā)者與RESTful服務(wù)輕松通信;
集成(Integration) :Jersey還提供可以輕松繼承Spring、Guice、Apache Abdera的庫。
在本次開發(fā)中使用Jersey2.0,并且僅使用了核心服務(wù)器。
設(shè)置Jersey環(huán)境
Maven
<!--jersey--> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet-core</artifactId> <version>2.0</version> </dependency> <!--JAXB API--> <dependency> <groupId>javax.xml.ws</groupId> <artifactId>jaxws-api</artifactId> <version>2.1</version> </dependency> <!-- Json支持 --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.12</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-jaxrs</artifactId> <version>1.9.12</version> </dependency>
引入Jar文件方式
從Jersey開發(fā)包中將以下庫復(fù)制的WEB-INF下的庫目錄:
1 服務(wù)器:jersey-server.jar 、jersey-container-servlet-core.jar、jersey-container-servlet.jar、javax.ws.rs-api-2.0.jar
2 客戶端:jersey-client.jar
3 common:jersey-common.jar
4 json支持:在Jersey2.0中需要使用 Jackson1.9 才能支持json。
Hello World
以下將展示一個Hello World
第一步: 編寫一個名為HelloResource的資源,它接受Http Get請求并響應(yīng)“Hello Jersey”
@Path("/hello") public class HelloResource { @GET @Produces(MediaType.TEXT_PLAIN) public String sayHello() { return "Hello Jersey"; } }
第二步: 編寫JAX-RS application
public class APIApplication extends ResourceConfig { public APIApplication() { //加載Resource register(HelloResource.class); //注冊數(shù)據(jù)轉(zhuǎn)換器 register(JacksonJsonProvider.class); // Logging. register(LoggingFilter.class); } }
第三步: 在web.xml文件中定義servelt調(diào)度程序,目的是將所有REST請求發(fā)送到Jersey容器。除了聲明Jersey Servlet外,還需定義一個初始化參數(shù),指定JAX-RS application。
<!--用于定義 RESTful Web Service 接口--> <servlet> <servlet-name>JerseyServlet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>cn.com.mink.resource.APIApplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JerseyServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
在命令終端中輸入以下命令,將會看到“Hello Jersey”。
curl http://host:port/services/hello
或者在瀏覽器中輸入以下URL,將會看到“Hello Jersey”
http://host:port/services/hello
使用
資源
Root Resource And Sub-Resource
資源是組成RESTful服務(wù)的關(guān)鍵部分,可以使用HTTP方法(如:GET、POST、PUT和DELETE)操作資源。在JAX-RX中,資源通過POJO實現(xiàn),使用 @Path 注釋組成其標(biāo)識符。資源可以有子資源,父資源是資源集合,子資源是成員資源。
在以下樣例代碼中,
Resources是"/services" URI組成是集合資源,UserResource是“/services/user” URI組成的成員資源;
@Path("/services") public class Resources { @Path("/user") public UserResource getUserResource() { ... } @Path("/book") public BookResource getBookResource() { ... } }
UserResource是“/user” URI組成的集合資源,getUser是“/user/{username}” URI組成的資源方法
@Path("/user") public class UserResource { @GET @Path("{username"}) @Produces("application/json") public User getUser(@PathParam("username") String userName) { ... } }
HTTP Methods
HTTP方法映射到資源的CRUD(創(chuàng)建、讀取、更新和刪除)操作,基本模式如下:
HTTP GET :讀取/列出/檢索單個或資源集合。
HTTP POST :新建資源。
HTTP PUT :更新現(xiàn)有資源或資源集合。
HTTP DELETE :刪除資源或資源集合。
@Produces
@Produces 注釋用來指定將要返回給client端的數(shù)據(jù)標(biāo)識類型(MIME)。@Produces 可以作為class注釋,也可以作為方法注釋,方法的 @Produces 注釋將會覆蓋class的注釋。
1 指定一個MIME類型
@Produces("application/json")
2 指定多個MIME類型
@Produces({"application/json","application/xml"})
@Consumes
@Consumes 與 @Produces 相反,用來指定可以接受client發(fā)送過來的MIME類型,同樣可以用于class或者method,也可以指定多個MIME類型,一般用于 @PUT ,@POST 。
參數(shù)(Parameter Annotations)
Parameter Annotations用于獲取client發(fā)送的數(shù)據(jù)。本文只介紹常用的注解,更多詳見 Jersey用戶手冊
@PathParam
使用 @PathParam 可以獲取URI中指定規(guī)則的參數(shù),比如:
@GET @Path("{username"}) @Produces(MediaType.APPLICATION_JSON) public User getUser(@PathParam("username") String userName) { ... }
當(dāng)瀏覽器請求 http://localhost/user/jack 時,userName值為jack。
@QueryParam
@QueryParam 用于獲取GET請求中的查詢參數(shù),如:
@GET @Path("/user") @Produces("text/plain") public User getUser(@QueryParam("name") String name, @QueryParam("age") int age) { ... }
當(dāng)瀏覽器請求 http://host:port/user?name=rose&age=25 時,name值為rose,age值為25。如果需要為參數(shù)設(shè)置默認(rèn)值,可以使用 @DefaultValue ,如:
@GET @Path("/user") @Produces("text/plain") public User getUser(@QueryParam("name") String name, @DefaultValue("26") @QueryParam("age") int age) { ... }
當(dāng)瀏覽器請求 http://host:port/user?name=rose 時,name值為rose,age值為26。
@FormParam
@FormParam ,顧名思義,從POST請求的表單參數(shù)中獲取數(shù)據(jù)。如:
@POST @Consumes("application/x-www-form-urlencoded") public void post(@FormParam("name") String name) { // Store the message }
@BeanParam
當(dāng)請求參數(shù)很多時,比如客戶端提交一個修改用戶的PUT請求,請求中包含很多項用戶信息。這時可以用 @BeanParam 。
@POST @Consumes("application/x-www-form-urlencoded") public void update(@BeanParam User user) { // Store the user data }
User Bean定義如下:
@XmlRootElement(name = "user") public class User { @PathParam("userName) private String userName; @FormParam("name") private String name; @FormParam("telephone") private String telephone; @FormParam("email") private String email; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } ... }
使用Map
在一個大型的server中,因為參數(shù)的多變,參數(shù)結(jié)構(gòu)的調(diào)整都會因為以上幾種方式而遇到問題,這時可以考慮使用 @Context 注釋,并獲取UriInfo實例,如下:
@GET public String get(@Context UriInfo ui) { MultivaluedMap<String, String> queryParams = ui.getQueryParameters(); MultivaluedMap<String, String> pathParams = ui.getPathParameters(); }
同樣還可以通過 @Context 注釋獲取 ServletConfig 、 ServletContext 、HttpServletRequest 、 HttpServletResponse 和 HttpHeaders 等,如下:
@Path("/") public class Resource { @Context HttpServletRequest req; @Context ServletConfig servletConfig; @Context ServletContext servletContext; @GET public String get(@Context HttpHeaders hh) { MultivaluedMap<String, String> headerParams = hh.getRequestHeaders(); Map<String, Cookie> pathParams = hh.getCookies(); } }
Jersey返回Json和Xml
JAX-RS支持使用JAXB(Java API for XML Binding)將JavaBean綁定到XML或JSON,反之亦然。JavaBean必須使用 @XmlRootElement 標(biāo)注,沒有@XmlElement 注釋的字段將包含一個名稱與之相同的XML元素,如下:
@XmlRootElement public class OptionResult { @XmlElement(name = "code") private String result; private String errorMsg; public String getResult() { return result; } public void setResult(String result) { this.result = result; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } }
然后在REST服務(wù)中使用:
@Path("/user") public class UserResource { @POST @Produces("application/json") public OptionResult create(@BeanParam User user) { ... } }
最后,要注冊數(shù)據(jù)轉(zhuǎn)換器,該轉(zhuǎn)換器會自動將JavaBean轉(zhuǎn)換為json數(shù)據(jù):
public class APIApplication extends ResourceConfig { public APIApplication() { //加載Model register(OptionResult.class); //加載與OptionResult同一個packge的Model //packages(OptionResult.class.getPackage().getName()); //加載Resource register(UserResource.class); //注冊數(shù)據(jù)轉(zhuǎn)換器 register(JacksonJsonProvider.class); // Logging. register(LoggingFilter.class); } }
說明 :返回XML數(shù)據(jù)的原理相同,僅僅是數(shù)據(jù)轉(zhuǎn)換器不同,只需要在APIApplication中同時注冊XML數(shù)據(jù)轉(zhuǎn)換器即可,詳見 Jersey用戶手冊
問題總結(jié)
Ajax請求(POST、PUT和DELETE)無法將數(shù)據(jù)提交到Jersey容器
問題闡述
在短信平臺的開發(fā)中,數(shù)據(jù)的CRUD全部使用Ajax技術(shù)完成,因此必須使用POST、PUT和DELETE請求。此三種請求的content-type均為“application/x-www-form-urlencoded”,使用UTF-8編碼會變成“application/x-www-form-urlencoded; UTF-8”。在使用Firefox的tamperdata擴(kuò)展調(diào)試程序的過程中發(fā)現(xiàn),當(dāng)content-type為“application/x-www-form-urlencoded”時,Jersey容器能夠通過 @FormParam 注解獲取到提交的數(shù)據(jù),而content-type為“application/x-www-form-urlencoded; UTF-8”時便獲取不到。
解決方案
最終我使用Java Filter和Jersey RequestFilter解決了問題。首先在Java Filter中使用UTF8將Request中的數(shù)據(jù)編碼,然后在Jersey RequestFilter中將request對象中的content-type修改為“application/x-www-form-urlencoded”。如:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; req.setCharacterEncoding("UTF-8"); } public class RequestFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext context) throws IOException { String headerString = context.getHeaderString("content-type"); if (headerString != null) { //如果content-type以"application/x-www-form-urlencoded"開頭,則處理 if (headerString.startsWith(MediaType.APPLICATION_FORM_URLENCODED)) context.getHeaders().putSingle("content-type", MediaType.APPLICATION_FORM_URLENCODED); } } }
最后在web.xml中注冊Java Filter(要注冊在Jersey容器之前),在APIApplication中注冊Jersey RequestFilter,如下:
public class APIApplication extends ResourceConfig { public APIApplication() { register(RequestFilter.class); } }
看完這篇關(guān)于詳解JAVA中Jersey框架的文章,如果覺得文章內(nèi)容寫得不錯的話,可以把它分享出去給更多人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。