使用jersey(2.5.1)搭建java REST服务
2015-07-21 16:49
961 查看
本文涉及的环境及测试工具
java8,netbean8,jersey2.5.1,tomcat8
WizTools3.5
注意:一定要用netbean管理的jersey库,从网上下的jar包不全,在测试json输出时会报异常
其它的jar
JAX-RS2.0,javax.json-1.0.1
至于cdi注入,因为jersey的库中使用的是hk2,可以使用
![](https://img-blog.csdn.net/20150721163238013)
开始吧.
1.实体举例
User bean
BankCard bean
说明,因为bankcard可以输出为application/xml,所以需要加上jaxb的注解:@XmlRootElement
2.服务层,接口层面不需要特别的注解,下面是业务接口的实现
说明,@Inject cdi注入注解,后面有一个hk2的配置类会告诉cdi去实例哪个实现类
3.dao层,接口照例没有需要的注解,接品实现我用的是jodd,这里没有什么特别要说的,官方给的说明很全面
4.hk2的配置类
说明,至所以我写成这样,其实也可以看出很容易把一个非服务的应用转成服务,当然是服务需要的注入
5.资源类(REST的重点部分)
说明
@Path 指明资源的路径,和下面的入口一起组合而成app/类的path/方法的path,@Path(“add/{id}”)中的{id}是路径参数,可以在方法参数(@PathParam(“id”)int uid),注意引号中的一定要对应路径占位字符,参数类型后面的可以不同
@GET, @PUT, @POST, @DELETE 和 @HEAD 是http协议中的请求方法
@Consumes 指定方法可以使用的请求正文体的mime-type类型,我使用的有:
POST对应的是@Consumes(“application/x-www-form-urlencoded”),这时方法的参数中使用@FormParam
PUT对应的是@Consumes({“application/json”,”application/xml”})
DELETE,GET 都是通过路径参数
@Produces 指定响应内容的mime-type类型,我觉得最后不好一个方法用xml,一个方法用json,最好统一,便于客户端程序处理,当然这个可以通过响应的内容类型(content-type),当然免不了使用if或者方法委托
其它
可以在方法参数中使用一些请求的头部内容@HeaderParam,请求中的cookie内容@CookieParam,或者path后面的查询字符串(query string)@QueryParam
在类中可以使用@Context获取上下文中的一些信息,例如javax.ws.rs.core.UriInfo,javax.ws.rs.core.Request
像你看到的如果要向客户端响应json/xml,不需要作特别的转换,方法直接输出bean实例
6.入口servlet
7.web.xml配置
java8,netbean8,jersey2.5.1,tomcat8
WizTools3.5
注意:一定要用netbean管理的jersey库,从网上下的jar包不全,在测试json输出时会报异常
其它的jar
JAX-RS2.0,javax.json-1.0.1
至于cdi注入,因为jersey的库中使用的是hk2,可以使用
开始吧.
1.实体举例
User bean
public class User implements Serializable{ /** * ID */ private int qiuid; /** * 用户名 */ private String name; /** * 手机号 */ private String phone; /** * 邮箱 */ private String mail; /** * 密码 */ private String pswd; /** * 注册日期 */ private Date regDate; /** * 最后活跃日期 */ private Date activeDate; /** * 注册IP */ private String regIP; /** * 最后活跃IP */ private String activeIP; /** * 因子 */ private String factor; /** * 状态 */ private boolean status; /** * 应用 */ private AppNode app; /** * 银行卡 */ private List<BankCard> cards; /** * 钱包 */ private Wallet wall; //ETC GET/SET }
BankCard bean
@XmlRootElement public class BankCard implements Serializable{ /** * ID(银行卡编号) */ private int id=0; /** * 银行名称 */ private String names; /** * 银行帐号 */ private String account; /** * 开户人 */ private String realname; /** * 银行地址:南大街支行 */ private String address; /** * 是否是默认的 */ private boolean isDefault=false; /** * 是否可用 */ private boolean status=true; /** * 关联的会员 */ private User user; //ETC get/set }
说明,因为bankcard可以输出为application/xml,所以需要加上jaxb的注解:@XmlRootElement
2.服务层,接口层面不需要特别的注解,下面是业务接口的实现
import javax.inject.Inject; import net.iqido.dao.UserDao; import net.iqido.entity.User; import net.iqido.service.UserService; /** * * @author Administrator */ public class UserServiceImple implements UserService { @Inject private UserDao userDao; @Override public int addUser(String username, String pswd, String phone, String mail) { System.out.println("[SEL]name:"+username); User u=new User(); u.setName(username); u.setPhone(phone); u.setPswd(pswd); u.setMail(mail); return userDao.addUser(u); } @Override public boolean lockUser(int qiuid) { return userDao.updateUserStatus(qiuid,false); } @Override public boolean updateUser(int qiuid, String oldpswd, String newpswd) { return userDao.updateUserPassword(qiuid, oldpswd, newpswd); } @Override public void offLineUser(int qiuid) { } @Override public int getUser(String username, String pswd) { return userDao.getUserFromUserName(username, pswd).getQiuid(); } @Override public boolean checkPhone(String phone) { return userDao.getUserFromPhone(phone)==null?false:true; } @Override public boolean checkMail(String mail) { return userDao.getUserFromMail(mail)==null?false:true; } @Override public boolean checkUserName(String name) { return userDao.getUserFromName(name)==null?false:true; } }
import javax.inject.Inject; import net.iqido.dao.BankCardDao; import net.iqido.entity.BankCard; import net.iqido.service.BankCardService; /** * * @author Administrator */ public class BankCardServiceImple implements BankCardService{ @Inject private BankCardDao bankCardDao; @Override public int addCard(BankCard card, int qiuid) { return bankCardDao.addBankCard(qiuid, card); } @Override public int lockCard(int id, int qiuid) { return bankCardDao.updateBankCardStatus(qiuid, id, false)?1:0; } @Override public boolean updateCard(int id, int qiuid, String names, String account, String realname) { BankCard b=new BankCard(); b.setId(id); b.setNames(names); b.setAccount(account); b.setRealname(realname); return bankCardDao.updateBankCard(qiuid, b); } @Override public BankCard getCard(int qiuid) { return bankCardDao.getBankCard(qiuid); } @Override public boolean setDefaultCard(int id, int qiuid) { return bankCardDao.updateBankCardIsDefault(qiuid, id, true); } }
说明,@Inject cdi注入注解,后面有一个hk2的配置类会告诉cdi去实例哪个实现类
3.dao层,接口照例没有需要的注解,接品实现我用的是jodd,这里没有什么特别要说的,官方给的说明很全面
4.hk2的配置类
import net.iqido.dao.*; import net.iqido.dao.imple.*; import net.iqido.service.*; import net.iqido.service.imple.*; import org.glassfish.hk2.utilities.binding.AbstractBinder; /** * CDI配置 * @author Administrator */ public class IqidoRestBuilder extends AbstractBinder{ @Override protected void configure() { //会员 bind(UserServiceImple.class).to(UserService.class); bind(UserDaoImple.class).to(UserDao.class); //银行卡 bind(BankCardServiceImple.class).to(BankCardService.class); bind(BankCardDaoImple.class).to(BankCardDao.class); }
说明,至所以我写成这样,其实也可以看出很容易把一个非服务的应用转成服务,当然是服务需要的注入
5.资源类(REST的重点部分)
import javax.annotation.ManagedBean; import javax.inject.Inject; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PUT; import net.iqido.entity.BankCard; import net.iqido.resource.tools.AppNodeAuth; import net.iqido.service.BankCardService; /** * 银行卡服务 * * @author Administrator */ @ManagedBean @Path("card") @AppNodeAuth public class CardResource { @Inject private BankCardService bankCardService;//=new BankCardServiceImple(); @Context private UriInfo context; /** * Creates a new instance of CardResource */ public CardResource() { } @POST @Path("add/{id}") @Produces("application/json") @Consumes("application/x-www-form-urlencoded") public BankCard add( @FormParam("name")String name, @FormParam("account")String account, @FormParam("real")String real, @FormParam("address")String address, @PathParam("id")int qiuid){ BankCard bc=new BankCard(); bc.setAccount(account); bc.setNames(name); bc.setRealname(real); bc.setAddress(address); bc.setId(bankCardService.addCard(bc, qiuid)); return bc; } @DELETE @Path("lock/{id}/{record}") public int lock( @PathParam("id")int qiuid, @PathParam("record")int id){ return bankCardService.lockCard(id, qiuid); } @PUT @Path("update/{id}/{record}") @Consumes("application/json") public boolean update( @PathParam("id")int qiuid, @PathParam("record")int id, BankCard card){ return bankCardService.updateCard(id, qiuid, card.getNames(), card.getAccount(), card.getRealname()); } @GET @Path("get/{id}") @Produces("application/json") public BankCard get(@PathParam("id")int qiuid){ return bankCardService.getCard(qiuid); } @PUT @Path("setting/{id}/{record}") @Consumes("application/json") public boolean setting(@PathParam("id")int qiuid,@PathParam("record")int id){ return bankCardService.setDefaultCard(id, qiuid); } }
import javax.annotation.ManagedBean; import javax.inject.Inject; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; import javax.ws.rs.PathParam; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Request; import net.iqido.resource.tools.AppNodeAuth; import net.iqido.service.UserService; /** * 会员服务 * * @author Administrator */ @ManagedBean @Path("user") @AppNodeAuth public class UserResource { @Inject private UserService userService; @Context private UriInfo context; @Context private Request request; public UserResource() { } @POST @Path("register") @Consumes("application/x-www-form-urlencoded") public int add( @FormParam("name")String username, @FormParam("pswd")String pswd, @FormParam("phone")String phone, @FormParam("mail")String mail) { return userService.addUser(username, pswd, phone, mail); } @POST @Path("login") @Consumes("application/x-www-form-urlencoded") public int get( @FormParam("name")String username, @FormParam("pswd")String userpswd) { //是否有必要返回一个预定的格式:{id:x,app:x,name:,phone:,mail:x,domain:} //或者直接由服务写入到cookie中 return userService.getUser(username, userpswd); } @POST @Path("reset/{id}") @Consumes("application/x-www-form-urlencoded") public boolean update( @PathParam("id")int qiuid, @FormParam("old")String oldpswd, @FormParam("used")String newpswd){ return userService.updateUser(qiuid, oldpswd, newpswd); } @GET @Path("logout/{id}") public String offline(@PathParam("id")int qiuid){ userService.offLineUser(qiuid); return "OK"; } @DELETE @Path("lock/{id}") public boolean lock(@PathParam("id")int qiuid){ return userService.lockUser(qiuid); } @GET @Path("check") public boolean checkUsername(@QueryParam("value")String option,@QueryParam("category")int cate){ boolean redate; switch(cate){ case 1: redate=userService.checkPhone(option); break; case 2: redate=userService.checkUserName(option); break; case 3: redate=userService.checkMail(option); break; default: redate=true; } return redate; } }
说明
@Path 指明资源的路径,和下面的入口一起组合而成app/类的path/方法的path,@Path(“add/{id}”)中的{id}是路径参数,可以在方法参数(@PathParam(“id”)int uid),注意引号中的一定要对应路径占位字符,参数类型后面的可以不同
@GET, @PUT, @POST, @DELETE 和 @HEAD 是http协议中的请求方法
@Consumes 指定方法可以使用的请求正文体的mime-type类型,我使用的有:
POST对应的是@Consumes(“application/x-www-form-urlencoded”),这时方法的参数中使用@FormParam
PUT对应的是@Consumes({“application/json”,”application/xml”})
DELETE,GET 都是通过路径参数
@Produces 指定响应内容的mime-type类型,我觉得最后不好一个方法用xml,一个方法用json,最好统一,便于客户端程序处理,当然这个可以通过响应的内容类型(content-type),当然免不了使用if或者方法委托
其它
可以在方法参数中使用一些请求的头部内容@HeaderParam,请求中的cookie内容@CookieParam,或者path后面的查询字符串(query string)@QueryParam
在类中可以使用@Context获取上下文中的一些信息,例如javax.ws.rs.core.UriInfo,javax.ws.rs.core.Request
像你看到的如果要向客户端响应json/xml,不需要作特别的转换,方法直接输出bean实例
6.入口servlet
import javax.ws.rs.ApplicationPath; import net.iqido.resource.rest.IqidoRestBuilder; import net.iqido.resource.tools.ApplicationCloudListener; import org.glassfish.jersey.server.ResourceConfig; /** * 入口点 * @author Administrator */ @ApplicationPath("app") public class RestServiceApplication extends ResourceConfig{ public RestServiceApplication(){ //扫描包 packages("net.iqido.resource.rest"); packages("net.iqido.resource.tools"); //HK2 CDI register(new IqidoRestBuilder()); register(ApplicationCloudListener.class); } }
7.web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <session-config> <session-timeout> 30 </session-timeout> </session-config> <servlet> <servlet-name>RESTFulApp</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>net.iqido.web.RestServiceApplication</param-value> </init-param> <init-param> <param-name>javax.json.stream.JsonGenerator.prettyPrinting</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>RESTFulApp</servlet-name> <url-pattern>/app/*</url-pattern> </servlet-mapping> </web-app>
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统