使用 Spring AOP控制Controller输出

来源:互联网 发布:海康网络键盘 编辑:程序博客网 时间:2024/06/05 22:51


1. pom.xml  引入spring aop 的相关jar

<!-- depend on Aop Api --><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!-- supply Dynamic Proxy --><dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>3.2.0</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.7</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.7</version></dependency>

2. spring.xml aop配置
<!-- AOP --><!-- 通过aop命名空间的<aop:aspectj-autoproxy/>声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面;proxy-target-class=false,表示使用jdk动态代理织入增强;proxy-target-class=true,表示使用CGLib动态代理技术织入增强; 不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。 --><aop:aspectj-autoproxy proxy-target-class="true" />

3. 自定义message-converters配置

<mvc:annotation-driven><mvc:message-converters register-defaults="true"><bean class="com.pixshow.spring.JsonHttpMessageConverter" /><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg value="UTF-8" /><property name="supportedMediaTypes"><list><value>text/plain;charset=UTF-8</value><value>text/xml;charset=UTF-8</value></list></property></bean><!--<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> --><!--<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/> --><!--<bean class="org.springframework.http.converter.FormHttpMessageConverter"/> --></mvc:message-converters></mvc:annotation-driven>

4. JsonHttpMessageConverter 代码
package com.pixshow.spring;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.nio.charset.Charset;import org.springframework.http.HttpInputMessage;import org.springframework.http.HttpOutputMessage;import org.springframework.http.MediaType;import org.springframework.http.converter.AbstractHttpMessageConverter;import org.springframework.http.converter.HttpMessageNotReadableException;import org.springframework.http.converter.HttpMessageNotWritableException;import org.springframework.util.FileCopyUtils;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;public class JsonHttpMessageConverter extends AbstractHttpMessageConverter<JSON> {    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");    /** Creates a new instance of the {@code ByteArrayHttpMessageConverter}. */    public JsonHttpMessageConverter() {        super(MediaType.APPLICATION_JSON);    }    @Override    protected boolean supports(Class<?> clazz) {        return JSON.class.isAssignableFrom(clazz);    }    @Override    protected JSONObject readInternal(Class<? extends JSON> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {        Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());        String jsonStr = FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));        return JSONObject.parseObject(jsonStr);    }    @Override    protected void writeInternal(JSON json, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {        Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());        outputMessage.getHeaders().setContentType(MediaType.APPLICATION_JSON);        JSONObject rs = new JSONObject();        rs.put("status", 0);        rs.put("data", json);        if (json instanceof JSONObject) {            JSONObject data = JSONObject.parseObject(json.toJSONString());            if (data.containsKey("status") && data.getIntValue("status") == -999) {                rs = data;            }        }                FileCopyUtils.copy(rs.toString(), new OutputStreamWriter(outputMessage.getBody(), charset));    }    protected Charset getContentTypeCharset(MediaType contentType) {        if (contentType != null && contentType.getCharSet() != null) {            return contentType.getCharSet();        } else {            return DEFAULT_CHARSET;        }    }}


5. ApiControllerAspect代码
package com.pixshow.spring.exception;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.core.annotation.AnnotationUtils;import org.springframework.stereotype.Component;import org.springframework.util.StringUtils;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.alibaba.fastjson.JSONObject;@Component@Aspectpublic class ApiControllerAspect {    private final static Log log = LogFactory.getLog(ApiControllerAspect.class);    //execution(* cpm.pixshow.*Service*.*(..))    @Pointcut("execution(* *..*Controller.*(..))")    public void pointCut() {    }    @After("pointCut()")    public void after(JoinPoint joinPoint) {    }    @Before("pointCut()")    public void before(JoinPoint joinPoint) {    }    @AfterReturning(pointcut = "pointCut()", returning = "returnVal")    public void afterReturning(JoinPoint joinPoint, Object returnVal) {    }    @Around("pointCut()")    public Object around(ProceedingJoinPoint pjp) {        long start = System.currentTimeMillis();        String className = getRequestUrl();        Object obj = null;        boolean error = false;        try {            //继续执行            obj = pjp.proceed();        } catch (Throwable ex) {            //将错误输出到控制台            ex.printStackTrace();            error = true;        }        long end = System.currentTimeMillis();        if(error) {            JSONObject rs = new JSONObject();            rs.put("status", -999);            rs.put("data", "error");            obj = rs;            log.error((end - start) + "ms " + className);        } else {            log.info((end - start) + "ms " + className);        }        return obj;            }    //这一步将永远都不会走,因为上面不会抛出错误异常    @AfterThrowing(pointcut = "pointCut()", throwing = "error")    public void afterThrowing(JoinPoint point, Throwable error) {        String className = getRequestUrl();        log.error(className + " :" + error);    }    /**     * 获取Request Url     * @param joinPoint     * @return     * @throws Exception     *     */    public static String getRequestUrl() {        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        StringBuffer url = request.getRequestURL();        return url.toString();    }  }

6. 测试
    @RequestMapping(value = "ccc")    public @ResponseBody JSONObject ccc() {        int m = 1/0;        CityBean bean = new CityBean();        bean.setName("1111111111");        bean.seteName("1111111111");        cityService.saveCity(bean);        JSONObject result = JSON.parseObject(JSON.toJSONString(bean));        return result;    }
请求http://127.0.0.1:8088/MapGeoService/ccc
页面显示:
控制台输出:
java.lang.ArithmeticException: / by zeroat com.pixshow.google.controller.CityController.ccc(CityController.java:33)at com.pixshow.google.controller.CityController$$FastClassBySpringCGLIB$$299d8103.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)...at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:745)2015-12-15 18:07:40 ERROR (ApiControllerAspect.java:70) - 4ms http://127.0.0.1:8088/MapGeoService/ccc



0 0