基于Jersey的拼车APP REST API POST请求无法更新仓库列表
POST新增行程后GET无法获取的问题分析与解决
我一眼就看出问题所在了——你的RideResource和RideRepository的生命周期不匹配导致的!
问题根源
Jersey默认对资源类(比如你的RideResource)采用**每请求实例化(per-request)**的策略:也就是说,每次收到GET或POST请求,Jersey都会新建一个RideResource对象。而你在RideResource里直接new RideRepository(),这意味着每个请求都会得到一个全新的RideRepository实例,里面的rides列表都是初始化的那两个行程。
- 当你发POST请求时,新行程确实被添加到了当前请求对应的
RideRepository实例里,但请求结束后这个实例就被销毁了; - 下次发GET请求时,Jersey又新建了一个
RideResource,随之新建的RideRepository里还是初始的两个行程,自然看不到新增的数据。
解决方案
有几种简单的修复方式,选哪种取决于你的项目规模:
方案1:把RideRepository改成静态变量(快速修复)
直接在RideResource里把repo改成静态变量,这样所有请求都会共享同一个RideRepository实例:
@Path("rides") public class RideResource { // 静态变量确保全局唯一实例 private static RideRepository repo = new RideRepository(); @GET @Produces(MediaType.APPLICATION_JSON) public List<Ride> getRides() { return repo.getRides(); } @POST @Path("ride") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Ride createRide(Ride r1) { System.out.println(r1); repo.createRide(r1); System.out.println(repo.getRides()); // 现在打印的是全局共享的列表 return r1; } }
方案2:给RideResource添加@Singleton注解
让Jersey只创建一个RideResource实例,这样里面的repo自然也是全局共享的:
@Path("rides") @Singleton // 关键注解:指定资源类为单例 public class RideResource { RideRepository repo = new RideRepository(); // 下面的GET、POST方法保持不变 }
方案3:用依赖注入注册单例Repository(适合复杂项目)
如果你的项目后续会扩展,推荐用Jersey自带的HK2依赖注入,把RideRepository注册为单例:
- 先给
RideRepository添加@Singleton注解:
@Singleton public class RideRepository { // 原有代码不变 }
- 在你的Jersey应用配置类里注册这个单例:
public class MyApplication extends ResourceConfig { public MyApplication() { register(RideResource.class); register(RideRepository.class); } }
- 在
RideResource里通过@Inject注入RideRepository:
@Path("rides") public class RideResource { @Inject private RideRepository repo; // 方法不变 }
额外提醒
不管用哪种方案,这种内存存储的方式都是临时的——Tomcat重启、应用重新部署后,所有新增的行程都会丢失。如果是生产环境,建议把行程数据持久化到数据库里哦。
内容的提问来源于stack exchange,提问作者contemplator
相关产品推荐
相关产品推荐

