Spring Aspect获取request和response
2016-08-11 10:58
417 查看
最近在项目中把给客户端的protobuf结构转换成给网页端的json,可以直接使用spring的aspect拦截controller层的方法,然后拿到request和response进行转换。spring我使用的是全注解方式。其实这里有2个坑:
如何在spring aspect中获取HttpServletRequest和HttpServletResponse。
获取到request和response后pb转json重新输出出现乱码。会抛出java.io.CharConversionException: Not an ISO 8859-1 character异常。
其实在spring的aspect中很好获取HttpServletRequest和HttpServletResponse,通过spring-web模块下的RequestContextHolder就能获取到。spring-web对servlet的上下文进行了封装,可以看到是通过NamedThreadLocal进行封装的。
通过静态方法getRequestAttributes取出。
可以通过如下代码获取request:
而response可以这样:
pb转换json也不复杂,使用google提供的工具类JsonFormat.printToString即可。但是在通过response输出时会遇到剩下的那俩个问题。当输出json有中文时,会出现字符集无法转换的异常,网上给出的解决方案是用从response中获取PrintWriter对象,但是如果使用PrintWriter就会出现接下来的writer已经被调用的问题,产生java.lang.IllegalStateException: getOutputStream() has already been called for this response异常,所以还是转回SerlvetOutPutStream。
最后完整的代码如下:
如何在spring aspect中获取HttpServletRequest和HttpServletResponse。
获取到request和response后pb转json重新输出出现乱码。会抛出java.io.CharConversionException: Not an ISO 8859-1 character异常。
其实在spring的aspect中很好获取HttpServletRequest和HttpServletResponse,通过spring-web模块下的RequestContextHolder就能获取到。spring-web对servlet的上下文进行了封装,可以看到是通过NamedThreadLocal进行封装的。
通过静态方法getRequestAttributes取出。
可以通过如下代码获取request:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
而response可以这样:
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
pb转换json也不复杂,使用google提供的工具类JsonFormat.printToString即可。但是在通过response输出时会遇到剩下的那俩个问题。当输出json有中文时,会出现字符集无法转换的异常,网上给出的解决方案是用从response中获取PrintWriter对象,但是如果使用PrintWriter就会出现接下来的writer已经被调用的问题,产生java.lang.IllegalStateException: getOutputStream() has already been called for this response异常,所以还是转回SerlvetOutPutStream。
最后完整的代码如下:
@Aspect @Component public class PB2JsonAspect { public static final Logger LOGGER = LogManager.getLogger(PB2JsonAspect.class); private static final String RESPONSE_CHARSET = "UTF-8"; @Pointcut("execution(* fm.jiecao.rest.*.controller.*.*(..))") public void PB2JsonAfter() { } @AfterReturning(pointcut = "PB2JsonAfter()", returning = "returnValue") public void afterReturning(Object returnValue) { LOGGER.info("PB2JsonAspect afterReturning..."); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();//获取request HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();//获取response if (checkHasFlag(request) && checkReturnValueIsPb(returnValue)) { String json = JsonFormat.printToString((Message) returnValue);//转换json ServletOutputStream out = null; try { response.setCharacterEncoding(RESPONSE_CHARSET); response.setContentType("text/json;charset=" + RESPONSE_CHARSET); out = response.getOutputStream(); out.write(json.getBytes(RESPONSE_CHARSET)); LOGGER.debug("pb->json:" + json); } catch (IOException e) { e.printStackTrace(); } finally { if (null != out) { try { out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } } } private boolean checkReturnValueIsPb(Object returnValue) { if (returnValue instanceof Message) {//检查是否是pb return true; } else { return false; } } private boolean checkHasFlag(HttpServletRequest request) { if (null == request) return false; String contentType = request.getContentType(); String accept = request.getHeader("Accept"); //检查accept和content-type if (StringUtils.isNotBlank(contentType) && contentType.contains("application/json") || StringUtils.isNotBlank(accept) && accept.contains("application/json") ) { return true; } else { return false; } } }
相关文章推荐
- spring如何获取request response session
- Spring 手动获取request和response
- Spring获取request和response
- Spring集成CXF客户端获取HttpServletRequest,HttpServletResponse
- Spring AOP中获取request,response
- @Spring MVC 中几种获取request和response的方式
- springmvc + AOP 获取Controller HttpServletRequest及HttpServletResponse
- spring中获取request和response
- DWR获取request,response,session值
- Struct2获取response和request的方法
- Java中通过DWR获取session、request、response
- (转)Spring AOP 取得 web 的 request response 和 session
- LoadRunner获取WEB请求头信息的方法:REQUEST、RESPONSE
- java 程序中获取session/request/response/上下文路径等对象
- Struts2中action获取request、response、session的方式
- Struts2中action获取request、response、session的方式
- struts2如何获取Request-Session-ServletContext-Response
- spring AOP 取得 web 的 request response 和 session
- struts2中获取action中request,response,session的方法
- Struts 2 中对 request、response、session的获取