对 REST 和 Jersey 来说相当新,我正在尝试一些基本示例。我有一个特别的问题,我还没有真正找到答案(真的不知道如何寻找这个):你将如何存储/定义公共服务,以便它们是有状态的和可访问的到所有/一些资源?
例如,一个记录器实例(Log4J 或其他)。我是否必须手动初始化它并将其存储在 HttpSession 中?是否有这样做的“最佳实践”方式,以便我的记录器可以访问所有/某些资源?
严格说起 Logger,你确定要它是有状态的吗?我参与的大多数项目只是在任何需要它的课程中抓住一个
Logger log = Logger.getLogger(this.getClass().getName());
到处剪切和粘贴,让伐木魔法开始!
关于保持状态的原始问题:您是否希望在每个用户(如会话)或整个应用程序中保持某些其他状态(如运行时配置的记录器)?会话可以通过 HttpRequest 和一些 ServletFilters 来管理。像这样在您的 Jersey 代码中获取请求
@Path("/awesome")
public class AwesomeService {
@GET
@Produces("text/awesome")
public String getAwesome(@Context HttpServletRequest req) {
HttpSession session= req.getSession(true);
//brilliance
}
}
应用程序资源,如实体管理器或 konfabulator 可以静态初始化并用作单例或工厂。
class EntityManager {
EntityManager manager;
public static EntityManager getManager() {
if(manager == null) {
manager = initManager();
}
return manager;
}
}
您最好的选择是使用 Spring 之类的方法将服务注入到资源中。在您的资源中为特定服务添加一个 setter 使其可用于各种范围。以下教程详细解释了如何使用 Spring 和 Jersey。以下是完成这项工作所需的各种部件的示例。专门回答您的问题,但是“最佳实践”是允许 Spring 管理特定服务的“有状态”或“范围”。
简单的服务 Bean
public class SimpleBean {
private int counter;
public String sayHello() {
return Integer.toString(counter++);
}
}
简单的 JAX-RS 资源
public class HelloWorldResource {
private SimpleBean simpleBean;
public void setSimpleBean(SimpleBean simpleBean) {
this.simpleBean = simpleBean;
}
@GET @Path("/Hello") @Produces(MediaType.APPLICATION_JSON)
public String sayHello() {
return "{\"Hello\": \"" + this.simpleBean.sayHello() + "\"}";
}
}
简单的 Spring applicationContext.xml,注意 Bean 和 Resource 的“范围”。这定义了这些对象的状态。
<bean id="simpleBean" scope="prototype" class="myhealth.spring.SimpleBean"/>
<bean id="helloWorldResource" scope="singleton" class="myhealth.ajax.HelloWorldResource">
<property name="simpleBean">
<ref bean="simpleBean"/>
</property>
</bean>