一个Forums的小示例,来总体看一看用jersey(2.22.2)来架设一个RESTful Web服务.
1.实体类,包名:net.iqido.bbs.entity
import javax.xml.bind.annotation.XmlRootElement;
/** * 实体:帐户/会员 * @author xiaofanku */
@XmlRootElement
public class Account {
private int uid;
private String mail;
//ETC set/get
}
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
/** * 实体:话题 * @author xiaofanku */
@XmlRootElement
public class Topic {
private long id;
private String title;
private Account author;
private Date publish;
//ETC get/set
}
2.用来分页显示实体的范型类,包名:net.iqido.bbs.util
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import net.iqido.bbs.entity.Topic;
/** * 注意:没有XmlSeeAlso注解无法解析 * @author xiaofanku * @param <T> */
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@XmlSeeAlso({Topic.class})
public class PageList<T> {
@XmlElement
private int total;
@XmlElement
private int page;
@XmlElement
private int pageSize;
@XmlElementWrapper
@XmlElement
private List<T> result;
//ETC set/get
}
3.RESTful资源,包名:net.iqido.bbs
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.Application;
/** * app应用配置 * @author xiaofanku */
@javax.ws.rs.ApplicationPath("app")
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<>();
addRestResourceClasses(resources);
resources.add(org.glassfish.jersey.moxy.json.MoxyJsonFeature.class);
resources.add(JsonMoxyConfigurationContextResolver.class);
return resources;
}
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(net.iqido.bbs.TopicResource.class);
}
}
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import net.iqido.bbs.entity.Account;
import net.iqido.bbs.entity.Topic;
import net.iqido.bbs.util.PageList;
import org.glassfish.jersey.server.JSONP;
/** * 话题资源 * @author xiaofanku */
@Path("topic")
public class TopicResource {
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
public Topic get(@PathParam("id")long id){
//测试数据
Account a=new Account();
a.setUid(1);
a.setMail("[email protected]");
Topic c=new Topic();
c.setId(100010);
c.setAuthor(a);
c.setTitle("this is demo title1");
c.setPublish(new Date());
return c;
}
@POST
@Path("build")
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Topic post(
@FormParam("title")String title,
@FormParam("account")int uid,
@FormParam("author")String mail){
//测试数据
Account a=new Account();
a.setUid(uid);
a.setMail(mail);
Topic c=new Topic();
c.setId(10);//increment
c.setAuthor(a);
c.setTitle(title);
c.setPublish(new Date());//now()
return c;
}
@GET
@JSONP(callback = "eval", queryParam = "jsonpCallback")
@Path("list/{page}/{pageSize}")
@Produces({"application/xml; qs=0.9", "application/json","application/javascript"})
public PageList<Topic> today(@PathParam("page")int page,@PathParam("pageSize")int pageSize){
//测试数据
Account a=new Account();
a.setUid(1);
a.setMail("[email protected]");
List<Topic> result=new ArrayList<>();
Topic c=new Topic();
c.setId(100010);
c.setAuthor(a);
c.setTitle("this is demo title1");
c.setPublish(new Date());
Topic c1=new Topic();
c1.setId(10010);
c1.setAuthor(a);
c1.setTitle("this is demo title2");
c1.setPublish(new Date());
result.add(c);
result.add(c1);
PageList<Topic> all=new PageList<>();
all.setResult(result);
all.setTotal(2);
all.setPage(page);
all.setPageSize(pageSize);
return all;
}
}
import javax.ws.rs.ext.ContextResolver;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.glassfish.jersey.moxy.json.MoxyJsonConfig;
/** * Eclipse Moxy json转换 * @author xiaofanku */
class JsonMoxyConfigurationContextResolver implements ContextResolver<MoxyJsonConfig> {
private final MoxyJsonConfig config;
public JsonMoxyConfigurationContextResolver() {
this.config = new MoxyJsonConfig()
.setAttributePrefix("")
.setValueWrapper("value")
.property(JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, true)
.setFormattedOutput(true)
.setIncludeRoot(true)
.setMarshalEmptyCollections(true);
}
@Override
public MoxyJsonConfig getContext(Class<?> type) {
return config;
}
}
4.Maven pom.xml依赖
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.2</version>
</dependency>
<!-- Required only when you are using JAX-RS Client -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.22.2</version>
<scope>compile</scope>
</dependency>
5.环境
开发IDE:NetBeans 8.1
运行:Apache Tomcat/8.0.27
JVM:1.7.0_80-b15
注意:在GlassFish4.1.1中运行,会报以下异常:
java.lang.ClassNotFoundException: org.xml.sax.helpers.DefaultHandler not found by org.eclipse.persistence.moxy [276]
这主要是因为GF的modules中的org.eclipse.persistence.moxy版本问题.
bug报告可以查看
NoClassDefFoundError when doing bean validation
Webservices don’t work properly in 4.1.1
6.测试服务是否正常可以在地址中输入:
http://localhost:8084/forums/app/application.wadl
测试xml和json内容类型
测试jsonp
示例下载地址:http://download.csdn.net/detail/xiaofanku/9458987