前面我们介绍了如何使用Jersey完成增删改查接口的开发,如果您想了解,可以参考:
Dropwizard 中使用Jersey开发Restful接口(查询接口)
Dropwizard 中使用Jersey开发Restful接口(响应报文格式、新增)
Dropwizard 中使用Jersey开发Restful接口(修改、删除)
本篇我们在前面的案例的基础上,实现持久层代码与资源层代码的分离,并使用依赖注入完成持久层对象的注入。
我们在db包下编写GoodsRepository类:
public class GoodsRepository {
private static List goodsList = new ArrayList<>();
static {
goodsList.add(new Goods("1", "薯片"));
goodsList.add(new Goods("2", "可口可乐"));
}
/**
* 查询商品
* @return
*/
public List find() {
return this.goodsList;
}
/**
* 根据ID查询商品
* @param id
* @return
*/
public Goods findById(String id) {
for (Goods goods: goodsList) {
if(goods.getId().equals(id)) {
return goods;
}
}
return null;
}
/**
* 插入
* @param goods
*/
public void insert(Goods goods) {
goodsList.add(goods);
}
/**
* 更新
* @param goods
*/
public void update(Goods goods) {
for (Goods g: goodsList) {
if(g.getId().equals(goods.getId())) {
g.setName(goods.getName());
break;
}
}
}
/**
* 删除
* @param id
*/
public void delete(String id) {
for (Iterator it = goodsList.iterator(); it.hasNext(); ) {
Goods goods = it.next();
if(goods.getId().equals(id)) {
it.remove();
break;
}
}
}
}
这里我们在持久类中完成了数据的增删改查功能
@Path("/goods")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class GoodsResource {
private final GoodsRepository goodsRepository;
@GET
public Response find() {
return Response.ok().entity(new ResponseResult(0, "成功", this.goodsRepository.find())).build();
}
@POST
public Response add(Goods goods) {
// 判断商品是否为空
if(Objects.isNull(goods)) {
return Response.ok().entity(new ResponseResult(502, "商品不能为空")).build();
}
// 判断商品编号是否为空
if(Objects.isNull(goods.getId())
|| goods.getId().isBlank()) {
return Response.ok().entity(new ResponseResult(502, "商品编号不能为空")).build();
}
// 判断商品名称是否为空
if(Objects.isNull(goods.getName())
|| goods.getName().isBlank()) {
return Response.ok().entity(new ResponseResult(502, "商品名称不能为空")).build();
}
// 根据商品编号查询商品
Goods hadGoods = this.goodsRepository.findById(goods.getId());
if(Objects.nonNull(hadGoods)) {
return Response.ok().entity(new ResponseResult(502, "商品编号已经存在")).build();
}
// 添加商品
this.goodsRepository.insert(goods);
return Response.ok().entity(new ResponseResult(0, "成功", goods)).build();
}
@PUT
@Path("/{id}")
public Response update(@PathParam("id") String id, Goods goods) {
// 查询商品
Goods hadGoods = this.goodsRepository.findById(id);
// 判断商品是否存在
if(Objects.isNull(hadGoods)) {
return Response.ok().entity(new ResponseResult(404, "商品不存在")).build();
}
// 修改商品名称
goods.setId(id);
this.goodsRepository.update(goods);
return Response.ok().entity(new ResponseResult(0, "成功", goods)).build();
}
@DELETE
@Path("/{id}")
public Response delete(@PathParam("id") String id) {
// 查询商品
Goods hadGoods = this.goodsRepository.findById(id);
// 判断商品是否存在
if(Objects.isNull(hadGoods)) {
return Response.ok().entity(new ResponseResult(404, "商品不存在")).build();
}
// 删除商品
this.goodsRepository.delete(id);
return Response.ok().entity(new ResponseResult(0, "成功", hadGoods)).build();
}
}
资源类改造后不再进行数据上的处理了,数据上的处理全部放在了持久类中,资源类通过调用持久类中的方法完成数据上的处理。
上面,我们虽然完成了持久类、资源类的编写;但资源类中的goodsRepository变量未初始化实例,当然可以通过new的方式进行创建实例,但是这样就增加了类之间的依赖;所以这里我们使用依赖注入的方式将GoodsRepository实例注入到资源对象中。
NamedProperty类:用于定义注入对象的属性
value代表的是注入的对象
id代表的是注入的对象的名称
clazz代表的是注入的对象的类型
public class NamedProperty {
private final String id;
private final T value;
private final Class clazz;
public NamedProperty(String id, T value, Class clazz) {
this.id = id;
this.value = value;
this.clazz = clazz;
}
public String getId() {
return id;
}
public T getValue() {
return value;
}
public Class getClazz() {
return clazz;
}
}
DependencyInjectionConfiguration接口:用于定义依赖注入的配置
public interface DependencyInjectionConfiguration {
/**
* 获取单例类列表
* @return
*/
List> getSingletons();
/**
* 获取注入对象的属性列表
* @return
*/
List> getNamedProperties();
}
项目配置类(我这里的是HorseConfiguration;项目搭建完成默认是trueConfiguration)实现上面定义的DependencyInjectionConfiguration接口;
public class HorseConfiguration extends Configuration implements DependencyInjectionConfiguration {
@Override
public List> getSingletons() {
final List> result = new ArrayList();
result.add(GoodsRepository.class);
result.add(GoodsResource.class);
return result;
}
@Override
public List> getNamedProperties() {
return new ArrayList<>();
}
}
在GoodsRepository、GoodsResource使用注入注解:
@Singleton
public class GoodsRepository {
}
@Singleton
public class GoodsResource {
private final GoodsRepository goodsRepository;
@Inject
public GoodsResource(GoodsRepository goodsRepository) {
this.goodsRepository = goodsRepository;
}
}
@Singleton:代表的是单例
@Inject:代表的是注入对象
实现依赖注入捆绑包:
public class DependencyInjectionBundle implements ConfiguredBundle {
@Override
public void run(DependencyInjectionConfiguration configuration, Environment environment) {
environment.jersey()
.register(new AbstractBinder() {
@Override
protected void configure() {
for (Class> singletonClass: configuration.getSingletons()) {
// 绑定单例
bindAsContract(singletonClass).in(Singleton.class);
}
for (NamedProperty extends Object> namedProperty: configuration.getNamedProperties()) {
// 注入对象
bind((Object) namedProperty.getValue()).to((Class
修改主类(我这里的是HorseApplication;项目搭建完成默认是trueApplication):
@Override
public void run(final HorseConfiguration configuration,
final Environment environment) {
// 注册资源
environment.jersey().register(GoodsResource.class);
// 依赖注入
DependencyInjectionBundle dependencyInjectionBundle = new DependencyInjectionBundle();
dependencyInjectionBundle.run(configuration, environment);
}
查询所有的商品
请求方式:GET
请求地址:http://localhost:8080/goods
响应结果如下:
{
"code": 0,
"msg": "成功",
"data": [
{
"id": "1",
"name": "薯片"
},
{
"id": "2",
"name": "可口可乐"
}
]
}