使用jersey(2.5.1)搭建java REST服务

本文涉及的环境及测试工具
java8,netbean8,jersey2.5.1,tomcat8
WizTools3.5

注意:一定要用netbean管理的jersey库,从网上下的jar包不全,在测试json输出时会报异常

其它的jar
JAX-RS2.0,javax.json-1.0.1
至于cdi注入,因为jersey的库中使用的是hk2,可以使用
使用jersey(2.5.1)搭建java REST服务_第1张图片

开始吧.
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>

使用jersey(2.5.1)搭建java REST服务_第2张图片

你可能感兴趣的:(java,json,JAXB,REST,jersey)