您的位置:首页 > 编程语言 > ASP

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:

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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: