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実装フレームワークである.
に頼る
使用中に次の依存を追加します.
ここではJersey 2を使っています.
Spring boot
Spring bootはサーバを構築するのが簡単なので、ここではSpring bootを使って紹介します.Spring bootプロジェクトでJerseyを統合するのは簡単です.
依存関係の追加
リソースの定義
Resourceの登録
@SpringBootApplication注記のクラスに登録する
起動するとRestfulにアクセスできます.http://localhost:8080/restful/application.wadl
テスト
テストにはCallのRestfulが必要です.ここではjersey-clientパッケージを使って、以下の依存を加えます.
Resource
Resourceクラスを定義することは、実は私たちのリソース、すなわちURIを定義することです.実際の使用では、良いURIを定義するには、Root Resource、Sub-resourcesがあります.
Root Resource
ルートリソースクラス:@Pathで注釈されたPOJOs(通常の旧Javaオブジェクト)です.実は@Pathはクラスを注釈し、クラス内のメソッドに@GET、@PUT、@POST、@DELETE定義を使用します.上のMyResourceはルートリソースクラスです.
ここでは@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はルートリソースクラスのメソッドにも使用できます.このとき、各注釈の方法はサブリソースです.
パラメータ注記
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
@PathParamは@Path("{}")の括弧内の値を解析します.アクセスhttp://localhost:8180/restful/lookup/info/2,このとき2はidとして解析されることが分かった.
@QueryParam
@QueryParamはURIの中を?その後のパラメータを解析します.たとえば、http://localhost:8180/restful/lookup/list?name=zw
@FormParam
テストの時、ここで私が使っているのはPOSTです.この注記を使用する場合は、formのコミット(「アプリケーション/x-www-form-urlencoded」)を指定します.アクセスしたURIはformとして解析される.http://localhost:8180/restful/lookup/update?name=zw&age=20
@FormDataParam
ファイルのアップロードに使用:
@HeaderParam
GETリクエストでHTTPヘッダの「User-Agent」をパラメータに解析します.http://localhost:8180/restful/lookup/hello
@CookieParam
クッキーのClientは以下の通りです.
@MatrixParam
上のクラスに新しいプロパティを追加
@BeanParam
次にアクセス方法を示します.
この時点でこのリソースにアクセスする場合、URIはセミコロンを使用する必要があります.ではなくなお、パラメータはURI中なのでPersonInfoでは、フィールド上で@QueryParamを使用します.のように
http://localhost:8080/restful/lookup/multiple;id=2;alias=zw;alias=kaka;alias=hust
@Context
Restを使用する場合、HttpServiceletRequestまたはURIの情報が必要になる場合があります.Jerseyは注入インタフェースも提供してくれました.
上記は注入方法です.もちろん、これらのインスタンスを現在のresourceのインスタンスに注入することもできます.
JSONサポート
Webサービスは、XMLの他にJSONデータを使用する傾向があり、データを転送する際には体積が小さくなります.JerseyはJSONに対するサポートを提供し、要求内容はJSONである.公式サイトでは3つの方法が提供されています.しかし、私が使っている間に、解析できないことに気づきました.原因も見つからなかった.
そしてregister feature
対応するBean
そしてClient call service
結果テストに失敗しました.まだ勉強中です
Jersey 1と2の違い
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の違い