1. 程式人生 > >Jersey 實踐:構建RESTful服務及解決跨域問題

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就行了。