Jersey是JAX-RS(JSR311)开源参考实现用于构建RESTful Web service,它包含三个部分:

  核心服务器(Core Server) 通过提供JSR 311中标准化的注释和API标准化,可以用直观的方式开发RESTful Web服务。

  核心客户端(Core Client) Jersey客户端API能够帮助开发者与RESTful服务轻松通信;

  集成(Integration) Jersey还提供可以轻松继承Spring、Guice、Apache Abdera的库

设置Jersey环境

Maven

<!--jersey-->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.0</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>

引入Jar文件方式 
从Jersey开发包中将以下库复制的WEB-INF下的库目录:

  服务器 jersey-server.jar 、jersey-container-servlet-core.jar、jersey-container-servlet.jar、javax.ws.rs-api-2.0.jar

  客户端: jersey-client.jar

  common: jersey-common.jar

  json支持:在Jersey2.0中需要使用Jackson1.9才能支持json。

Demo Hello Wolrd

第一步:编写一个名为HelloResource的资源,它接受Http Get请求并响应 ”Hello Jerset”

@Path("/hello")
public class HelloResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
return "Hello Jersey";
}
}

第二步:编写JAX-RS application

public class APIApplication extends ResourceConfig {
public APIApplication() {
//加载Resource
register(HelloResource.class); //注册数据转换器
register(JacksonJsonProvider.class); // Logging.
register(LoggingFilter.class);
}
}

第三步:在web.xml文件中定义servelt调度程序,目的是将所有REST请求发送到Jersey容器。除了声明Jersey Servlet外,还需定义一个初始化参数,指定JAX-RS application。

<!--用于定义 RESTful Web Service 接口-->
<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>cn.com.mink.resource.APIApplication</param-value>
</init-param> <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseyServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

第四步:测试程序 
在命令终端中输入以下命令,将会看到“Hello Jersey”。 
curl http://host:port/services/hello 
或者在浏览器中输入以下URL,将会看到“Hello Jersey” 
http://host:port/services/hello

使用

资源

Root Resource And Sub-Resource 
资源是组成RESTful服务的关键部分,可以使用HTTP方法(如:GET、POST、PUT和DELETE)操作资源。在JAX-RX中,资源通过POJO实现,使用@Path 注释组成其标识符。资源可以有子资源,父资源是资源集合,子资源是成员资源。 
Resources是”/services” URI组成是集合资源,UserResource是“/services/user” URI组成的成员资源;

注意,POJO是指简单的Java对象

@Path("/services")
public class Resources { @Path("/user")
public UserResource getUserResource() {
...
} @Path("/book")
public BookResource getBookResource() {
...
}
}

UserResource是“/user” URI组成的集合资源,getUser是“/user/{username}” URI组成的资源方法

大括号里的内容是参数,这样设置是合理的,因为username也会出现在url中,而path就是url的意思

@Path("/user")
public class UserResource {
@GET
@Path("{username"})
@Produces("application/json")
public User getUser(@PathParam("username") String userName) {
...
}
}

HTTP Methods 
HTTP方法映射到资源的CRUD(创建、读取、更新和删除)操作,基本模式如下:

  HTTP GET: 读取/列出/检索单个资源

  HTTP POST: 新建资源

  HTTP PUT: 更新现有资源或资源集合

  HTTP DELETE: 删除资源或资源集合

@Produces 
@Produces注释用来指定将要返回给client端的数据标识类型(MIME)。@Produces可以作为class注释,也可以作为方法注释,方法的@Produces注释将会覆盖class的注释。 覆盖的意思是假如方法声明了自己的Produce,那么以方法的为准,class的仅供参考
指定MIME类型 
@Produces(“application/json”) 
指定多个MIME类型 
@Produces({“application/json”,“application/xml”})

@Consumes 
@Consumes与@Produces相反,用来指定可以接受client发送过来的MIME类型,同样可以用于class或者method,也可以指定多个MIME类型,一般用于@PUT,@POST 。

参数(Parameter Annotations) 
Parameter Annotations用于获取client发送的数据。本文只介绍常用的注解,更多详见Jersey用户手册 
@PathParam 
使用@PathParam可以获取URI中指定规则的参数,比如:

@GET
@Path("{username"})
@Produces(MediaType.APPLICATION_JSON)
public User getUser(@PathParam("username") String userName) {
...
}

当浏览器请求http://localhost/user/jack时,userName值为jack。

注意,这里的username并不是说Key是username, value是jack而是说/usr/后面跟着的东西就是username,这里username只是个变量

至于key,value的形式,下面也有

@QueryParam 
@QueryParam用于获取GET请求中的查询参数,如:

@GET
@Path("/user")
@Produces("text/plain")
public User getUser(@QueryParam("name") String name,
@QueryParam("age") int age) {
...
}

当浏览器请求http://host:port/user?name=rose&age=25时,name值为rose,age值为25。如果需要为参数设置默认值,可以使用@DefaultValue,如:

@GET
@Path("/user")
@Produces("text/plain")
public User getUser(@QueryParam("name") String name,
@DefaultValue("26") @QueryParam("age") int age) {
...
}

当浏览器请求http://host:port/user?name=rose时,name值为rose,age值为26。

@FormParam 
@FormParam,顾名思义,从POST请求的表单参数中获取数据。如:

@POST
@Consumes("application/x-www-form-urlencoded")
public void post(@FormParam("name") String name) {
// Store the message
}

表单我一直没弄清楚到底是什么东西,但就使用的情况来看,就是key,value之类的东西

BeanParam 
当请求参数很多时,比如客户端提交一个修改用户的PUT请求,请求中包含很多项用户信息。这时可以用@BeanParam。 
User Bean定义如下:

@XmlRootElement(name = "user")
public class User {
@PathParam("userName) //我觉得这个应该是写错了,FormParam
private String userName; @FormParam("name")
private String name; @FormParam("telephone")
private String telephone; @FormParam("email")
private String email; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
}
...
}

使用Map 
在一个大型的server中,因为参数的多变,参数结构的调整都会因为以上几种方式而遇到问题,这时可以考虑使用@Context 注释,并获取UriInfo实例,如下:

@GET
public String get(@Context UriInfo ui) {
MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
MultivaluedMap<String, String> pathParams = ui.getPathParameters();
}

我觉得,可以认为map是上面几种情况的超集,因为它能够替代以上任意一种。map就是context

同样还可以通过@Context 注释获取ServletConfig、ServletContext、HttpServletRequest、HttpServletResponse和HttpHeaders等,如下:

@Path("/")
public class Resource { @Context
HttpServletRequest req; @Context
ServletConfig servletConfig; @Context
ServletContext servletContext; @GET
public String get(@Context HttpHeaders hh) {
MultivaluedMap<String, String> headerParams = hh.getRequestHeaders();
Map<String, Cookie> pathParams = hh.getCookies();
}
}

Jersey返回Json和Xml 
JAX-RS支持使用JAXB(Java API for XML Binding)将JavaBean绑定到XML或JSON,反之亦然。JavaBean必须使用@XmlRootElement标注,没有@XmlElement注释的字段将包含一个名称与之相同的XML元素,如下:

这里就说明了javabean和xml, json的关系

@XmlRootElement
public class OptionResult {
@XmlElement(name = "code")
private String result; private String errorMsg; public String getResult() {
return result;
} public void setResult(String result) {
this.result = result;
} public String getErrorMsg() {
return errorMsg;
} public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}
然后在REST服务中使用:
@Path("/user")
public class UserResource {
@POST
@Produces("application/json")
public OptionResult create(@BeanParam User user) {
...
}
}

最后,要注册数据转换器,该转换器会自动将JavaBean转换为json数据:

public class APIApplication extends ResourceConfig {
public APIApplication() {
//加载Model
register(OptionResult.class); //加载与OptionResult同一个packge的Model
//packages(OptionResult.class.getPackage().getName()); //加载Resource
register(UserResource.class); //注册数据转换器
register(JacksonJsonProvider.class); // Logging.
register(LoggingFilter.class);
}
}

说明:返回XML数据的原理相同,仅仅是数据转换器不同,只需要在APIApplication中同时XML数据转换器即可。

Wiki上关于REST的总结

含状态传输(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格.

  资源是由URI来指定。

  对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。

  通过操作资源的表现形式来操作资源。

  资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。

应该注意区别应用的状态和连接协议的状态。HTTP连接是无状态的(也就是不记录每个连接的信息),而REST传输会包含应用的所有状态信息,因此可以大幅降低对HTTP连接的重复请求资源消耗。

实现举例:

每种操作都会对应一个函数

列举所有商品

GET http://www.store.com/products

呈现某一件商品

GET http://www.store.com/product/12345

下单购买

POST http://www.store.com/order
<purchase-order>
<item> ... </item>
</purchase-order>

REST的优点

  可更高效利用缓存来提高响应速度

  通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性

  浏览器即可作为客户端,简化软件需求

  相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小

  不需要额外的资源发现机制

  在软件技术演进中的长期的兼容性更好

JavaBean

JavaBeans是Java语言中可以重复使用的软件组件,它们是一种特殊的Java类[1],将很多的对象封装到了一个对象(bean)中。特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性。

优点

  Bean可以控制它的属性,事件和方法是否暴露给其他程序

  Bean可以接收来自其他对象的事件,也可以产生事件给其他对象

  有软件可以配置Bean

  Bean的属性可以被序列化,以供日后使用

JavaBean规范

要成为JavaBean类,必须遵循关于命名,构造器,方法的特定规范,有了这些规范,才能使用,复用,替代和连接javabean的工具。 
规范是:

  有一个public 无参构造器

  属性可以通过get, set, is方法或者遵循特定命名规范的其他方法访问。

  可序列化

一个例子

public class PersonBean implements java.io.Serializable {

    /**
* <code>name</code>属性(注意大小写)
*/
private String name = null; private boolean deceased = false; /** 无参构造器(没有参数) */
public PersonBean() {
} /**
* <code>name</code>属性的Getter方法
*/
public String getName() {
return name;
} /**
* <code>name</code>属性的Setter方法
* @param value
*/
public void setName(final String value) {
name = value;
} /**
* "deceased"属性的Getter方法
* 布尔型属性的Getter方法的不同形式(这里使用了is而非get)
*/
public boolean isDeceased() {
return deceased;
} /**
* <code>deceased</code>属性的Setter方法
* @param value
*/
public void setDeceased(final boolean value) {
deceased = value;
}
}

总结

1. Javabean提供了一种保证,即对于所有的成员变量,一定有get,set方法。并且还可以序列化

2. REST服务基于底层的保证来实现,因此可以简化很多事情,比如Javabean和XML的转换就可以写得相当简单。

Jersey 入门与Javabean的更多相关文章

  1. Java Restful框架:Jersey入门示例(官方例子)

    本文主要介绍了Java Restful框架Jersey入门例子(来源于官方网站https://jersey.java.net/),废话不多说进入正题. 在Jersey官方示例中(https://jer ...

  2. JAVA入门[12]-JavaBean

    一.什么是JavaBean JavaBean是特殊的Java类,使用Java语言书写,并且遵守规范: 提供一个默认的无参构造函数. 需要被序列化并且实现了Serializable接口. 可能有一系列可 ...

  3. Jersey入门——对Json的支持

    Jersey rest接口对POJO的支持如下: package com.coshaho.learn.jersey; import java.net.URI; import javax.ws.rs.C ...

  4. Jersey入门——注解的使用

    本文主要解释Jersey中各种注解的使用 package com.coshaho.learn.jersey; import java.net.URI; import javax.ws.rs.Consu ...

  5. Jersey入门三:创建一个JavaEE的Web项目

    1.在终端中输入如下命令,创建一个名为的simple-service-webapp项目: mvn archetype:generate -DarchetypeArtifactId=jersey-qui ...

  6. Jersey入门一:从Maven Archetype创建jersey项目

    1.用Ctrl+空格调出Spotlight搜索,输入ter调出终端窗口  2.在终端窗口进入将创建jersey项目的目录:  3.输入如下命令,创建一个名为的simple-service项目: m ...

  7. Jersey入门二:运行项目

    1.项目有了,在终端窗口进入项目的根目录(即 \simple-service ) 2.现在先测试运行下: mvn clean test  项目将会被编译,并且进行单元测试  上面可以看看到测试通过 ...

  8. JAVA入门--目录

    在此记录自己的JAVA入门笔记,备忘 JAVA入门[1]--安装JDK JAVA入门[2]-安装Maven JAVA入门[3]—Spring依赖注入 JAVA入门[4]-IntelliJ IDEA配置 ...

  9. java 与大数据学习较好的网站

    C# C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!https://www.cnblogs.com/doforfuture/p/6293926.html ...

随机推荐

  1. hbase源码系列(十)HLog与日志恢复

    HLog概述 hbase在写入数据之前会先写入MemStore,成功了再写入HLog,当MemStore的数据丢失的时候,还可以用HLog的数据来进行恢复,下面先看看HLog的图. 旧版的HLog是实 ...

  2. JavaScript(五):变量的作用域

    一.变量的分类 在JavaScript中变量分为两种: 全局变量 局部变量 二.变量的作用域 1.局部变量的作用域 局部变量:在函数内部定义的变量称为局部变量,其作用域为该函数内部,在该函数外部不能被 ...

  3. 多线程三:Task

    Task是.NET 3.0中推出的,是基于ThreadPool封装的,里面的线程都是来自于ThreadPool. 1.使用Run()方法启动线程 F12查看Run()方法的定义: 发现Run()方法的 ...

  4. PCL中点云数据格式之间的转化

    (1) 关于pcl::PCLPointCloud2::Ptr和pcl::PointCloud<pcl::PointXYZ>两中数据结构的区别 pcl::PointXYZ::PointXYZ ...

  5. OpenH264编译ffmpeg android

    思科的 安装NASM git clone https://github.com/cisco/openh264.git Android Builds install android sdk and nd ...

  6. Axiom3D:Ogre射线与点,线,面相交,鼠标操作3维空间.

    在第一篇网络分解成点,线,面.第二篇分别点以球形,线以圆柱,面分别以MergerBatch整合批次显示.因为整合批次显示后,相应的点,线,面不能以Ogre本身的射线来选取,因为整合后,以点举例,多个点 ...

  7. Android WiFi 日志记录(四次握手)

    记录一下四次握手的log. PMK: PMK(Pairwise Master Key,成对主密钥 STA和AP得到PMK后,将进行密匙派生以得到PTK.最后,PTK被设置到硬件中, 用于数据的加解密. ...

  8. android wifi RSSI达到阈值自动断开

    设置wifi的RSSI达到阈值之后自动断开. wifi状态改变,会更新状态栏,在状态栏中更改. --- a/packages/SystemUI/src/com/android/systemui/sta ...

  9. Lambda动态排序

    private static IList<T> IListOrderBy<T>(IList<T> list, string propertyName) where ...

  10. Android开发之获取相册照片和获取拍照照片二

    转至 http://blog.csdn.net/beyond0525/article/details/8940840 上一篇文章中讲解了照相机获取照片的时候遇到了可能取得的uri为null的状态,并给 ...