參考鏈接:https://www.iteye.com/blog/dyygusi-2148029?from=singlemessage&isappinstalled=0
測試代碼:
https://gitee.com/jiawenzhang/jersey-hello
https://gitee.com/jiawenzhang/jersey-client
webservice框架jersey簡單總結
項目中更需要使用到webservice,具體的是使用jersey。那么首先需要了解jersey和webservice的關系,捋順webservice框架的各種實現,通過查閱相關博客,我個人總結webservice的結構圖如下:
通過上圖,大概可以了解到webservice和jersey的關系了,然后我們需要了解RESTful是什么,自己也是說不太清楚,所以可以看這個博客地址:REST介紹:http://redhacker.iteye.com/blog/1923226
然后,知道了一些概念上的定義,就可以具體使用jersey,自己做了jerseyDemo來簡單說名jersey的使用。另外,jersey1.X的版本是sun公司提供的獨立的jar包,在2.X版本中,已經將jersey放在glassfish下。同時Java也支持jersey的webservice,支持webservice的注解的包都在javax.ws.rs.*包中。
jersey常用注解解釋:
Annotation | 作用 | 說明 |
@GET | 查詢請求 | 相當於數據庫的查詢數據操作 |
@POST | 插入請求 | 相當於數據庫的插入數據操作 |
@PUT | 更新請求 | 相當於數據庫的更新數據操作 |
@DELETE | 刪除請求 | 相當於數據的刪除數據操作 |
@Path | uri路徑 | 定義資源的訪問路徑,client通過這個路徑訪問資源。比如:@Path("user") |
@Produces | 指定返回MIME格式 | 資源按照那種數據格式返回,可取的值有:MediaType.APPLICATION_XXX。比如:@Produces(MediaType.APPLICATION_XML) |
@Consumes | 接受指定的MIME格式 | 只有符合這個參數設置的請求再能訪問到這個資源。比如@Consumes("application/x-www-form-urlencoded") |
@PathParam | uri路徑參數 | 寫在方法的參數中,獲得請求路徑參數。比如:@PathParam("username") String userName |
@QueryParam | uri路徑請求參數 | 寫在方法的參數中,獲得請求路徑附帶的參數。比如:@QueryParam("desc") String desc |
@DefaultValue | 設置@QueryParam參數的默認值 | 如果@QueryParam沒有接收到值,就使用默認值。比如:@DefaultValue("description") @QueryParam("desc") String desc |
@FormParam | form傳遞的參數 | 接受form傳遞過來的參數。比如:@FormParam("name") String userName |
@BeanParam | 通過Bena的形式傳遞參數 | 接受client傳遞的bean類型的參數,同時這個bean可以在屬性上配置@FormParam用以解決client的屬性名稱和bean的屬性名稱不一致的問題。比如:@BeanParam User user |
@Context | 獲得一些系統環境信息 | 通過@Context可以獲得以下信息:UriInfo、ServletConfig、ServletContext、HttpServletRequest、HttpServletResponse和HttpHeaders等 |
@XmlRootElement | 將bean轉換為xml | 如果要講bean以xml或json的格式返回,必須要這個注解。比如: @XmlRootElement public class User{...} |
@XmlElements | ||
@XmlElement |
Jersey使用示例:
1、添加Maven依賴或者導入jar包
<!--jersey --> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet-core</artifactId> <version>2.13</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> <!-- 編譯需要,tomcat里面有 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!-- 編譯需要,tomcat里面有 -->
|
沒有使用Maven的就自己下載相應的jar包,放到classpath下就是了。
2、修改web.xml,配置jerseyServlet
<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>com.cisdi.jersey.api.ApplicationAPI</param-value> </init-param> <!-- 配置默認的資源包路徑,使用默認的配置類去加載資源 --> <!-- <init-param> --> <!-- <param-name>jersey.config.server.provider.packages</param-name> --> <!-- <param-value>com.cisdi.jersey.api</param-value> --> <!-- </init-param> --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JerseyServlet</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping> |
上面有兩種加載資源的方式,一種是使用自己的資源加載器去加載資源,需要給出自己資源加載器的位置。另一種是使用默認的資源加載器加載,需要給出資源所在的package。個人主張第一種,寫一個自己的資源加載器去加載想要加載的資源,這樣感覺可控性強一點,接下來會介紹這個資源加載器如何編寫。
3、編寫自己的資源加載器
public class ApplicationAPI extends ResourceConfig { public ApplicationAPI() { // 加載resources register(HelloResource.class); register(UserResource.class);
// 注冊數據轉換器 register(JacksonJsonProvider.class);
// 注冊日志 register(LoggingFilter.class);
} } |
這個類就是將各種資源加載進來,暴露給client。之前說道使用自己的資源加載器可控性強的特點就是可以除了加載業務資源以外,還可以加載日子和其他的需要一些工具資源等等。或者package下的某個資源不想被暴露,就不要加載進來就可以了。
4、書寫自己的資源
先弄了一個簡單的資源,HelloResource
@Path("/hello") public class HelloResource { @GET @Produces(MediaType.TEXT_PLAIN) public String sayHello() { return "hello jersey!"; } } |
接着可以弄個復雜點得對象資源,UserResource
@XmlRootElement public class User { private int id; @FormParam("name") private String userName; @FormParam("desc") private String desc;
Setter/Getter... } |
下面就是UserResource的各個方法 @Path("user") public class UserResource { //這個類的方法都在下面 |
//這個方法主要介紹@GET,@Path,@Produces,@PathParam,@DefaultValue,@QueryParam注解的使用 @GET @Path("{username}") @Produces(MediaType.APPLICATION_XML) // @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public User getUser(@PathParam("username") String userName, @DefaultValue("description") @QueryParam("desc") String desc) { User user = new User(); user.setId(new Random().nextInt()); user.setUserName(userName); user.setDesc(desc); return user; } //訪問路徑:{host}:{port}/{serviceName}/api/user/username?desc=xxx ;username可以隨便寫 |
//這個方法主要介紹@POST,@Consumes,@FormParam注解的使用 @POST @Path("updateUser") @Consumes("application/x-www-form-urlencoded") public void updateUser(@FormParam("name") String userName, @FormParam("desc") String desc) { User user = new User(); user.setId(1); user.setUserName(userName); user.setDesc(desc); System.out.println(user); } //訪問路徑:{host}:{port}/{serviceName}/api/user/updateUser;這個是通過提交表單訪問的 |
//這個方法主要介紹@BeanParam的使用 @POST @Path("updateUser1") @Produces(MediaType.APPLICATION_XML) @Consumes("application/x-www-form-urlencoded") public User updateUser1(@BeanParam User user) { //注意這個方法需要在User這個bean中使用@FromParam注解 System.out.println(user); return user; } //訪問路徑:{host}:{port}/{serviceName}/api/user/updateUser1;這個是通過提交表單訪問的 |
//這個方法主要介紹@Context注解的使用 @Context HttpServletRequest request;
@Context HttpServletResponse response;
@Context ServletConfig servletConfig;
@Context ServletContext servletContext;
@Context HttpHeaders header;
@Context UriInfo info;
@GET @Path("/test/{param}") @Produces(MediaType.APPLICATION_XML) public User getContext() { MultivaluedMap<String, String> queryParameters = info.getQueryParameters(); MultivaluedMap<String, String> pathParameters = info.getPathParameters();
System.out.println(queryParameters); System.out.println(pathParameters);
System.out.println(this.request); System.out.println(this.response); System.out.println(this.servletConfig); System.out.println(this.servletContext); System.out.println(this.header); System.out.println(this.info);
return new User(1, "gusi");
} //訪問路徑:{host}:{port}/{serviceName}/api/user/test/xxx?xxx=xxx&xxx=xxx;xxx都是可以亂寫的 說明:使用這種方式有很大的作用,當我們不知道client傳遞過來的參數名稱,或者client傳遞過來的參數經常變化, 那么我們就可以使用這樣方式動態的獲得傳遞給service的參數,然后再進行后續的處理 |
5、通過client程序訪問webservice
上面我們可以直接通過瀏覽器的地址訪問webservice,此外還可以通過專門的客戶端程序訪問,程序如下:
public class UserClient { private static String serverURI = "http://localhost:8080/jerseyDemo/api/user";
public static void getContext() { Client client = ClientBuilder.newClient(); WebTarget target = client.target(serverURI + "/test/context?one='abc'&two=2"); Response response = target.request().get(); response.close(); }
public static void addUser() { User user1 = new User(1, "name1", "desc1"); User user2 = new User(2, "name2", "desc2"); Client client = ClientBuilder.newClient(); WebTarget target = client.target(serverURI + ""); Response response = null; target.request().buildPost(Entity.entity(user1, MediaType.APPLICATION_XML)).invoke(); response = target.request().buildPost(Entity.entity(user2, MediaType.APPLICATION_XML)).invoke(); response.close(); }
public static void deleteUser() { Client client = ClientBuilder.newClient(); WebTarget target = client.target(serverURI + "/1"); Response response = target.request().delete(); response.close(); }
public static void updateUser() { User user = new User(1, "nameA", "descA"); Client client = ClientBuilder.newClient(); WebTarget target = client.target(serverURI + ""); Response response = target.request().buildPut(Entity.entity(user, MediaType.APPLICATION_XML)).invoke(); response.close(); }
public static void getUserById() { Client client = ClientBuilder.newClient(); // client.register(JacksonJsonProvider.class); WebTarget target = client.target(serverURI + "/1"); Response response = target.request().get(); User user = response.readEntity(User.class); System.out.println(user); response.close(); }
public static void getAllUser() { Client client = ClientBuilder.newClient(); WebTarget target = client.target(serverURI + ""); Response response = target.request().get(); String value = response.readEntity(String.class); System.out.println(value); response.close(); } } |
上面分別演示了通過Client程序給Service發送POST,PUT,DELETE,GET請求。
6、測試
使用junit單元測試,分別測試發送不同的請求
public class UserClientTest {
@Test public void testContext() { UserClient.getContext(); }
@Test public void testAddUser() { UserClient.addUser(); }
@Test public void testDeleteUser() { UserClient.deleteUser(); }
@Test public void testUpdateUser() { UserClient.updateUser(); }
@Test public void testGetUser() { UserClient.getUserById();
}
@Test public void testGetAllUser() { UserClient.getAllUser(); }
} |
通過上面的6個步驟,就可一簡單的實現webservice的基本使用。