Jersey入門

14449 ワード

Rest
RESTフルネームはRepresentational State Transfer、中国語:記述的状態遷移.どういう意味だ?説明しない.
簡単に言えば,RESTはWebアドレス(URI)を用いてリソースにアクセスし,動詞(HTTP要求)を用いてリソースを操作する.
動詞
動詞とは、実はHTTPリクエストです.RESTは、Webサービスプロトコルとして理解することができる.RESTは,要求メソッド,URIアドレス,応答コードに直接依存する下位HTTPプロトコル機能である.HTTPプロトコルは無状態であり,同様にRESTも無状態であることを知っている.
 
 
動詞
リソースの操作
対応DB操作
操作タイプ
GET
リソースへの読み取り専用アクセスの提供
SELECT
読み取り専用
POST
既存のリソースを更新するか、新しいリソースを作成します.
UPDATE
N/A
PUT
新しいリソースの作成
CREATE
べき乗等
DELETE
アセットを削除するには
DELETE
べき乗等
OPTIONS
リソースでサポートされているアクションの取得
 
読み取り専用
HEAD
HTTPヘッダのみを返し、HTTP bodyは返さない
 
読み取り専用
 
Jersey
前にRestを紹介した時はSpring+JAXBで実現していました.生産中、Jerseyの方が便利です.Jerseyはオープンソースで製品レベルのJAX-RS API実装フレームワークである.
に頼る
使用中に次の依存を追加します.
	
		
			javax.servlet
			javax.servlet-api
			3.1.0
		
		
			org.glassfish.jersey.containers
			jersey-container-servlet
			${jersey.version}
		
		
			org.glassfish.jersey.containers
			jersey-container-servlet-core
			${jersey.version}
		
		
			org.glassfish.jersey.media
			jersey-media-json-jackson
			${jersey.version}
		
	

	
		2.6
	

ここではJersey 2を使っています.
Spring boot
Spring bootはサーバを構築するのが簡単なので、ここではSpring bootを使って紹介します.Spring bootプロジェクトでJerseyを統合するのは簡単です.
依存関係の追加
		
			org.springframework.boot
			spring-boot-starter-jersey
		

リソースの定義
@Component
@Singleton
@Path("/resource")
public class MyResource {

    @GET
    public String hello() {
        return "Hello World";
    }
}

Resourceの登録
@SpringBootApplication注記のクラスに登録する
	@Bean
    public ResourceConfig resourceConfig() {
        ResourceConfig config = new ResourceConfig();
        config.register(MyResource.class);
        return config;
    }

起動するとRestfulにアクセスできます.http://localhost:8080/restful/application.wadl
テスト
テストにはCallのRestfulが必要です.ここではjersey-clientパッケージを使って、以下の依存を加えます.
		
			com.sun.jersey
			jersey-client
			1.18
		
		
			com.sun.jersey
			jersey-grizzly2
			1.18
		
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.ws.rs.core.Cookie;

import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertThat;


@RunWith(SpringRunner.class)
@SpringBootTest
public class KakaApplicationTests {

    @Test
    public void contextLoads() {
    }


    @Test
    public void getLightWeightShipment() {
        Client client = Client.create(new DefaultClientConfig());
        WebResource service = client.resource("http://localhost:8180/restful/lookup/tryCookie");
        Cookie cookie = new Cookie("sessionId", "mysession");

        String s1 = service.cookie(cookie).get(String.class);

        assertThat(s1, containsString("mysession"));
    }
}

 
 
 
 
 
Resource
Resourceクラスを定義することは、実は私たちのリソース、すなわちURIを定義することです.実際の使用では、良いURIを定義するには、Root Resource、Sub-resourcesがあります.
Root Resource
ルートリソースクラス:@Pathで注釈されたPOJOs(通常の旧Javaオブジェクト)です.実は@Pathはクラスを注釈し、クラス内のメソッドに@GET、@PUT、@POST、@DELETE定義を使用します.上のMyResourceはルートリソースクラスです.
@Component
@Singleton
@Path("/resource")
public class MyResource {

    @GET
    @Produces("text/plain")
    public String getHello() {
        return "Hello World";
    }

    @GET
    @Produces("text/html")
    public String getHelloPage() {
        return "hello

Hello World!

"; } @POST @Produces("text/plain") @Consumes({"text/plain", "application/xml"}) public String appendHello(@HeaderParam("User-Agent") String name) { return "Hello World : " + name; } }

ここでは@Singletonを使って一例を維持すればいいです.同様の注釈には@RequestScopedと@PerLookupがあります.
 
注釈
アクティブドメイン
説明する
@RequestScoped
Request scope
この役割ドメインは、注記なしでデフォルトで使用されます.一致するリソースクラスURIのリクエストごとにインスタンスが作成されます.
@PerLookup
Per-lookup scope
セッションごとにインスタンスを作成
@Singleton
Singleton
適用範囲内では、リソースクラスのインスタンスが1つしか作成されません.
ここでもHTTPリクエストのデータ型によって異なるレスポンスを提供する.
 
 
 
注釈
説明する
HTTPフィールド対応

@Consumes
http応答のMIMEタイプ配列タイプデフォルト*/*を指定し、任意のMIMEタイプを表します.
Content-Type
@Consumes(MediaType.TEXT_PLAIN) @Consumes({"text/plain", "application/xml"}) @Consumes("application/x-www-form-urlencoded")
@Produces
httpリクエストを指定するMIMEタイプ配列タイプデフォルトは*/*で、任意のMIMEタイプを表します.
Accept
@Produces("text/plain") @Produces({"application/xml", "application/json"})
 
Sub-resources
@Pathはルートリソースクラスのメソッドにも使用できます.このとき、各注釈の方法はサブリソースです.
@Path("/lookup")
public class LookupResource {

    @GET
    @Path("/info")
    @Produces({"application/json", "application/xml", MediaType.TEXT_PLAIN})
    public PersonInfo getInfo() {
        PersonInfo info = new PersonInfo();
        info.setName("Hustzw");
        info.setAge(20);
        info.setPhoneNo("12346789");
        return info;
    }

    @GET
    @Path("/list")
    @Produces({"application/json", "application/xml", MediaType.TEXT_PLAIN})
    public List getAll() {
        List list = new ArrayList<>();
        PersonInfo info = new PersonInfo();
        info.setName("Hustzw");
        info.setAge(20);
        info.setPhoneNo("12346789");
        list.add(info);

        PersonInfo info2 = new PersonInfo();
        info.setName("Kaka");
        info.setAge(21);
        info.setPhoneNo("9875645");
        list.add(info);
        return list;
    }
}

 
パラメータ注記
 
Jerseyはいくつかの@*Param形式の注釈を提供し、要求されたパラメータを自動的に解析するのに役立ちます.
 
注釈
さぎょう

@PathParam
@Pathと組み合わせて使用する場合は、@Pathで{}を使用してパスに一致するパラメータを指定します.
@Path("/info/{id}")パラメータ:@PathParam("id")String userId
QueryParam
urlのスペルを取得しますか?後のパラメータ
URI:x?Step=3パラメータ:@QueryParam("step")int step
FormParam
クライアントはform(MIMEがアプリケーション/x-www-form-urlencoded)を使用してフォームサービス側にコミット@FormParamを使用してformフォームのパラメータを解析する
@Consumes("application/x-www-form-urlencoded") ?name=zhangwei&age=20 @FormParam("name") String name, @FormParam("age") int age
FormDataParam
ファイルをアップロードする場合、@FormDataParamクライアントがform(MIMEはmultipart/form-data)をコミットする方法でフォームサービス側が@FormDataParamを使用してformフォームのパラメータを解析する必要があります
 
HeaderParam
httpリクエストヘッダのパラメータ値の取得
@HeaderParam("User-Agent") String name
CookieParam
httpリクエストヘッダのクッキーのパラメータ値の取得
 
MatrixParam
URLの「;」を選択します.同じkeyのものはすべてListに解析される
 
DefaultValue
@PathParam、@QueryParam、@FormParam、@FormDataParam、@MatrixParam、@HeaderParam、@CookieParamなどに合わせて使用する.要求指定されたパラメータに値がない場合、@DefaultValueの値を使用してデフォルト値の解析エラーが発生します404
 
BeanParam
要求パラメータをBeanに解析します.Beanのフィールドには@PathParam,@QueryParam,@FormParam,@FormDataParam,@MatrixParam,@HeaderParam,@CookieParamなどを用いて注記する
 
Context
注入に使用します.サーブレットに対するパッケージです.UriInfo、HttpHeader、ServertConfig、ServertContext、HttpServertRequest、HttpServertResponseなどを注入
 
Encoded
 
 
コードを見る
@PathParam
@Path("/lookup")
public class LookupResource {

    @GET
    @Path("/info/{id}")
    @Produces({"application/json", "application/xml", MediaType.TEXT_PLAIN})
    public PersonInfo getInfo(@PathParam("id") String id) {
        PersonInfo info = new PersonInfo();
        info.setId(id);
        info.setName("Hustzw");
        return info;
    }
}

@PathParamは@Path("{}")の括弧内の値を解析します.アクセスhttp://localhost:8180/restful/lookup/info/2,このとき2はidとして解析されることが分かった.
 
@QueryParam
    @GET
    @Path("/list")
    @Produces({"application/json", "application/xml", MediaType.TEXT_PLAIN})
    public List getAll(@QueryParam("name") String name) {// lookup/list?name=zw
        List list = new ArrayList<>();
        // ...
        return list;
    }

@QueryParamはURIの中を?その後のパラメータを解析します.たとえば、http://localhost:8180/restful/lookup/list?name=zw
 
@FormParam
    @POST
    @Path("/update")
    @Consumes("application/x-www-form-urlencoded")// lookup/list?name=zw&age=20
    @Produces({MediaType.TEXT_PLAIN})
    public String update(@NotNull @FormParam("name") String name, @DefaultValue("26") @NotNull @FormParam("age") int age) {
        return "success " + name + " "+ age;
    }

テストの時、ここで私が使っているのはPOSTです.この注記を使用する場合は、formのコミット(「アプリケーション/x-www-form-urlencoded」)を指定します.アクセスしたURIはformとして解析される.http://localhost:8180/restful/lookup/update?name=zw&age=20
 
@FormDataParam
ファイルのアップロードに使用:
 
@HeaderParam
    @GET
    @Path("/hello")
    @Produces("text/plain")
    @Consumes({"text/plain", "application/xml"})
    public String appendHello(@HeaderParam("User-Agent") String name) {
        return "Hello World : " + name;
    }

GETリクエストでHTTPヘッダの「User-Agent」をパラメータに解析します.http://localhost:8180/restful/lookup/hello
 
@CookieParam
    @GET
    @Path("/tryCookie")
    public String checkCookie(@CookieParam("sessionId") String sessionId) {
        return "Hello World : " + sessionId;
    }

クッキーのClientは以下の通りです.
    @Test
    public void getLightWeightShipment() {
        Client client = Client.create(new DefaultClientConfig());
        WebResource service = client.resource("http://localhost:8080/restful/lookup/tryCookie");
        Cookie cookie = new Cookie("sessionId", "mysession");

        String s1 = service.cookie(cookie).get(String.class);

        assertThat(s1, containsString("mysession"));
    }

 
@MatrixParam
上のクラスに新しいプロパティを追加
@XmlRootElement
public class PersonInfo implements Serializable {
    // ...
    @MatrixParam("alias")
    private List alias;
}

@BeanParam
次にアクセス方法を示します.
    @POST
    @Path("/multiple")
    public String checkAlias(@BeanParam PersonInfo info) {
        return "Hello World : " + info.getAlias().get(0);
    }

この時点でこのリソースにアクセスする場合、URIはセミコロンを使用する必要があります.ではなくなお、パラメータはURI中なのでPersonInfoでは、フィールド上で@QueryParamを使用します.のように
http://localhost:8080/restful/lookup/multiple;id=2;alias=zw;alias=kaka;alias=hust
 
@Context
Restを使用する場合、HttpServiceletRequestまたはURIの情報が必要になる場合があります.Jerseyは注入インタフェースも提供してくれました.
    @GET
    @Path("/viewpath")
    public String checkURI(@Context UriInfo ui) {
        return "Hello World : " + ui.getPath();
    }

上記は注入方法です.もちろん、これらのインスタンスを現在のresourceのインスタンスに注入することもできます.
@Path("/lookup")
public class LookupResource {

    @Context
    HttpServletRequest req;

    @Context
    ServletConfig servletConfig;

    @Context
    ServletContext servletContext;
    // ...
}

 
JSONサポート
 
Webサービスは、XMLの他にJSONデータを使用する傾向があり、データを転送する際には体積が小さくなります.JerseyはJSONに対するサポートを提供し、要求内容はJSONである.公式サイトでは3つの方法が提供されています.しかし、私が使っている間に、解析できないことに気づきました.原因も見つからなかった.
    @POST
    @Path("/place")
    @Consumes(MediaType.APPLICATION_JSON)
    public String place(@BeanParam DetailPlace country) {
        return "country " + country.getArea();
    }

そしてregister feature
@Component
@ApplicationPath("restful")
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(JacksonFeature.class);

        register(MyResource.class);
        register(ExampleResource.class);
    }
}

対応するBean
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class DetailPlace {

    @QueryParam("region")
    private String region;

    @QueryParam("area")
    private String area;

    public DetailPlace() {
    }

    public DetailPlace(String region, String area) {
        this.region = region;
        this.area = area;
    }
}

そしてClient call service
    @Test
    public void testResources() {
        ClientConfig cc = new DefaultClientConfig();
        Client client = Client.create(cc);
        WebResource service = client.resource("http://localhost:8080/restful/example/place");

        String result = service.header("Content-Type", "application/json").
                post(String.class, "{'region':'Asia','area':'976'}");

        assertThat(result, containsString("Asia"));
    }

結果テストに失敗しました.まだ勉強中です
 
 
Jersey 1と2の違い