最近有个小需求,关于Jersey[ver:2.7]+Spring[ver:3.2.3]的,要求在Jersey的Resource的方法上加上日志,首先想到了用Filter,但是Filter不能记录方法执行的结果,于是又想到了用Spring AOP来配置<aop:after-return/>来记录日志,于是拿jersey官方的例子中的“helloworld-spring-webapp”来做试验,结果发现不行,后来经过各种试验,算是找到一个了不是方法的方法,因为这个方法,要求Resource也要实现接口。不过无论如何,也做下记录,以便不时之需吧。
1. 定义接口,Jersey的annotation都要标注在接口上:
@Path("/test")
public interface ITestResource {
@GET
@Produces("text/plain;charset=UTF-8")
@Path("/getTest1")
public String getTest1();
@GET
@Produces("text/plain;charset=UTF-8")
@Path("/getTest2")
public String getTest2(@QueryParam("id") String id);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/readCustomer")
public Customer readCustomer(@QueryParam("id") int id);
@GET
@Produces("application/json;charset=UTF-8")
@Path("/readJson/{useaneme}/{age}")
public JaxbBean getJaxbBean(@PathParam("useaneme") String username, @PathParam("age") int age);
}
2. 实现此接口:(Customer、JaxbBean是普通Bean,为了测试JSON数据格式用的),
surveryBiz也可以用@Autowired来注入
public class TestResource implements ITestResource{
static Logger logger = LogManager.getLogger(TestResource.class.getName());
//@Autowired
private SurveryBiz surveryBiz;
public void setSurveryBiz(SurveryBiz surveryBiz) {
this.surveryBiz = surveryBiz;
}
public TestResource() {
logger.debug("TestResource:::::::");
}
public String getTest1() {
logger.trace("getTest1::::, no parameters" );
surveryBiz.answer();
return "REST GET TEST, no parameters";
}
public String getTest2(String id) {
logger.trace("getTest2::::::::, the parameters is id:" + id);
surveryBiz.answer();
return "REST GET TEST, the parameters is id:" + id;
}
public Customer readCustomer(int id) {
logger.trace("readCustomer::::::::::::");
surveryBiz.answer();
Customer customer = new Customer();
customer.setId(id);
customer.setName("Jane Doe");
PhoneNumber pn = new PhoneNumber();
pn.setType("work");
pn.setValue("5551111");
customer.getPhoneNumbers().add(pn);
return customer;
}
public JaxbBean getJaxbBean( String username, int age) {
logger.trace("getJaxbBean:::::::::" + username);
return new JaxbBean(username, age);
}
}
3. 实现一个SpringContextUtil.java:
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext; //Spring应用上下文环境
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
* @param applicationContext
* @throws org.springframework.beans.BeansException
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取对象
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
4. 实现jersey的TestApplication,注意红色字体:
@Path("rest")
public class TestApplication extends ResourceConfig {
/**
* Register JAX-RS application components.
*/
public RestApplication() {
//register(LogFilter.class);
register(RequestContextFilter.class);
register(AccountResource.class);
register(SpringContextUtil.getBean("testResource"));
//register(TestResource.class);
}
}
5. Spring配置文件
<bean name="springContextUtil" class="SpringContextUtil"/> <bean id="logService" class="LogServiceImpl"/> <bean name="testResource" class="TestResource"> <property name="surveryBiz" ref="surveryBiz"/> </bean> <aop:config> <!-- 切入点 --> <aop:pointcut id="logPointcut" expression="execution(* TestResource.*(..))"/> <!-- 切面: 将哪个对象中的哪个方法,织入到哪个切入点 --> <aop:aspect id="dd" ref="logService"> <aop:before method="log" pointcut-ref="logPointcut" /> <aop:after method="logArg" pointcut-ref="logPointcut"/> <aop:after-returning method="logArgAndReturn" returning="returnObj" pointcut-ref="logPointcut"/> </aop:aspect> </aop:config>