最近有个小需求,关于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>