使用javax-rs通过GET方法调用REST API无法获取预期值
嘿,这个问题我太熟了!核心原因是Jersey对资源类的默认生命周期管理——每次请求都会创建一个全新的Student实例。你在Main类里设置的是另一个完全独立的Student对象的属性,和处理GET请求的那个实例半毛钱关系都没有,所以接口自然只会返回int类型的默认值0啦。
根据你的需求,我给你几个可行的方案:
方案1:将Student资源改为单例作用域
如果你的需求是让所有请求共享同一个Student实例(比如全局维护一个学生信息),只需要给Student类加上@Singleton注解,这样Jersey只会创建一个实例,Main类设置的属性就能被所有请求获取到:
@Path("/student") @Singleton // 添加单例注解 public class Student{ int id; String name; // 你的setter方法 public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } @GET @Produces("text/plain") public int getALL(){ return id; } }
注意:这种方式适合全局共享的场景,但要注意线程安全问题——如果多个请求同时修改这个实例的属性,可能会出现并发问题,需要额外加锁处理。
方案2:通过请求参数传递数据
如果你的需求是每个请求获取不同的学生信息,那应该让请求携带参数,比如用@QueryParam或者@PathParam来接收:
@Path("/student") public class Student{ @GET @Produces("text/plain") // 通过QueryParam接收请求参数 public int getALL(@QueryParam("id") int id){ return id; } }
现在你访问接口的时候,只需要带上参数:http://your-domain/student?id=123,就能返回你传入的123了。
方案3:从外部数据源读取数据
如果你的学生信息是存储在数据库、配置文件或者其他外部存储中,那应该在getALL()方法里主动读取这些数据源的数据,而不是依赖Main类设置的实例属性:
@Path("/student") public class Student{ @GET @Produces("text/plain") public int getALL(){ // 这里从数据库/配置文件读取id值 return StudentDao.getStudentId(); } }
这种方式更符合REST接口的设计理念,因为每个请求都能获取到最新的数据源数据,也不会有实例共享的线程安全问题。
Jersey默认的资源类是请求作用域(per-request),也就是说每次请求都会初始化一个新的实例,实例变量会被重置为默认值。所以不要用实例变量来存储跨请求的状态,除非你明确指定了其他作用域(比如@Singleton、@SessionScoped)。
内容的提问来源于stack exchange,提问作者Sriram

