Jersey 實踐:構建RESTful服務及解決跨域問題
最近在準備為我的小程式做個後臺,剛好之前在網上了解了RESTful這種設計風格,覺得很簡單輕量,便準備採用這種設計方式。有很多框架都能支援RESTful的設計,在一番權衡之後,決定選擇jersey框架,因為我的小程式的併發量並不大,而且自己對於spring也還不太熟悉,而jersey框架寫起來很簡單,開發比較快。接下來便來講解如何用jersey完整的構建RESTful服務。
開發所使用IDE:Eclipse
開發環境:Maven、Jersey
因為jersey是基於maven的,所以大家要先裝好maven環境,具體方法請自行百度。
一、新建maven專案
具體就不贅述了。
二、匯入jersey的jar包
三、編寫程式碼
在src/main/java裡新建包,再新建兩個類:MyApplication和common
因為jersey是通過註解來識別不同的請求的,所以編寫起來十分方便
import javax.ws.rs.*; import javax.ws.rs.core.*; @Path("/common") //表示請求該類下的url時前面要加上/common,@Path裡的值不一定要與類名相同 public class common { @GET @Path("/hello") //訪問時是 /common/hello public String hello() { return "hello"; } }
@GET表示通過get請求,@Path表示請求時對應的url,當通過get請求/common/hello時會呼叫hello(),請求後伺服器將返回hello字串。怎麼樣?是不是很簡單?短短几行程式碼就能實現spring大量程式碼等同的功能。
接下來我們就要在MyApplication裡註冊我們的類了,也就是配置資源,因為REST認為每個url都是資源,只有註冊後訪問url才有效。
import org.glassfish.jersey.server.ResourceConfig; public class MyApplication extends ResourceConfig { public MyApplication() { register(common.class); } }
註冊也很簡單,通過繼承ResourceConfig,然後再在構造器裡通過register方法註冊我們的類,就行了。
四、配置xml
最後一步就是配置xml了,這個也不難。我們需要配置兩個web.xml檔案。第一個是WebContent裡的
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>auto_make_page</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>com.main.MyApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>com.main.MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
然後是下圖這個
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>com.main_servlet.MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.main.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>com.main_servlet.MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
注意這個的servlet-name是com.main_servlet.MyApplication,在所在包名後加上_servlet。
最後就可以把專案部署進tomcat運行了~~訪問的url是 /專案名/common/hello
jersey還有很多註解,能夠實現非常豐富的功能,大家可以到官網檢視。
【跨域問題解決】
我們在本地除錯遠端伺服器的api的時候,會遇到跨域問題。瀏覽器為了安全而不允許設定Access-Control-Allow-Origin的header,而伺服器為了安全也只允許當origin與域名相同時才能訪問。瀏覽器我們無法修改,但在服務端我們可以。程式碼如下:
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.container.*;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.ContainerResponse;
public class CorsFilter implements ContainerResponseFilter {
public ContainerResponse filter(ContainerRequest creq, ContainerResponse cres) {
cres.getHeaders().add("Access-Control-Allow-Origin", "*");
/**
* 允許的Header值,不支援萬用字元
*/
cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
/**
* 即使只用其中幾種,header和options是不能刪除的,因為瀏覽器通過options請求來獲取服務的跨域策略
*/
cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
/**
* CORS策略的快取時間
*/
cres.getHeaders().add("Access-Control-Max-Age", "1209600");
//可以通過 throw new WebApplicationException(Status.UNAUTHORIZED); 來中斷請求
return cres;
}
public void filter(ContainerRequestContext request, ContainerResponseContext cres) throws IOException {
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {//瀏覽器會先通過options請求來確認伺服器是否可以正常訪問,此時應放行
cres.setStatus(HttpServletResponse.SC_OK);
}
cres.getHeaders().add("Access-Control-Allow-Origin", "*");
cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
/**
* CORS策略的快取時間
*/
cres.getHeaders().add("Access-Control-Max-Age", "1209600");
}
}
最後把這個類也註冊進MyApplication就行了。