標籤:rest .com for log ack http gis lib error
在項目中遇到一個問題,需要對介面返回的資料進行加密給前端。項目中的controller一般都是返回一個實體form,重寫的一個視圖解析器繼承ModelAndViewResolver,對返回的form轉成json格式返回給前端。
視圖解析器:
public class JsonModelAndViewResolver implements ModelAndViewResolver,InitializingBean, ApplicationContextAware {private String defaultContentType = "text/html";private Log log = LogFactory.getLog(super.getClass());private JsonSerialization jsonSerialization;private ApplicationContext applicationContext;public void afterPropertiesSet() throws Exception {if (this.jsonSerialization != null)return;this.jsonSerialization = JsonSerializationFactory.getInstance(this.applicationContext);}public void setApplicationContext(ApplicationContext paramApplicationContext)throws BeansException {this.applicationContext = paramApplicationContext;}//執行這個方法public ModelAndView resolveModelAndView(Method paramMethod,Class paramClass, Object paramObject,ExtendedModelMap paramExtendedModelMap,NativeWebRequest paramNativeWebRequest) {if (Rest.class.isAssignableFrom(paramClass)) {try {HttpServletResponse localHttpServletResponse = (HttpServletResponse) paramNativeWebRequest.getNativeResponse(HttpServletResponse.class);responseJson(paramObject, localHttpServletResponse);} catch (IOException localIOException) {throw new WebException(localIOException.getMessage(),localIOException);}return null;}return UNRESOLVED;}public void responseJson(Object paramObject,HttpServletResponse paramHttpServletResponse) throws IOException {if (!(StringUtils.hasText(paramHttpServletResponse.getContentType())))paramHttpServletResponse.setContentType(this.defaultContentType);String str = writeResult(paramObject);PrintWriter localPrintWriter = paramHttpServletResponse.getWriter();if (this.log.isInfoEnabled())this.log.info("Rest result=" + str);if ("{}".equals(str)) {this.log.info("image stream is not write ");return;}localPrintWriter.write(str);localPrintWriter.flush();}protected String writeResult(Object paramObject) {String str = null;if (paramObject == null) {str = "{}";} else if ((paramObject instanceof Number)|| (paramObject instanceof Boolean)) {str = "{\"resultCode\":\"" + paramObject.toString() + "\"}";} else if ((paramObject instanceof String)) {String result = (String) paramObject;str = result;} else {if (paramObject instanceof ModelAndView)paramObject = ((ModelAndView) paramObject).getModel();str = getJsonSerialization().toJSONString(paramObject);}return str;}public String getDefaultContentType() {return this.defaultContentType;}public void setDefaultContentType(String paramString) {this.defaultContentType = paramString;}public JsonSerialization getJsonSerialization() {return this.jsonSerialization;}public void setJsonSerialization(JsonSerialization paramJsonSerialization) {this.jsonSerialization = paramJsonSerialization;}}
本來考慮直接修改視圖解析器,對返回json串加密,但發現項目中有些介面直接在controller中直接通過PrintWriter返回了參數,顯然有這種方法是攔截不到的。
最後通過HttpServletResponseWrapper截取返回資料流加密重新輸出給前端的方式。
代碼參照如下:
ResponseWrapper:
package com.paic.egis.smts.toa.web.interceptor;import java.io.CharArrayWriter;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;import com.paic.egis.smts.common.util.LoggerUtil;public class ResponseWrapper extends HttpServletResponseWrapper {private PrintWriter cachedWriter;private CharArrayWriter bufferedWriter;public ResponseWrapper(HttpServletResponse response) throws IOException {super(response);bufferedWriter = new CharArrayWriter();cachedWriter = new PrintWriter(bufferedWriter);}public PrintWriter getWriter() throws IOException {return cachedWriter;}public String getResult() {byte[] bytes = bufferedWriter.toString().getBytes();try {return new String(bytes, "UTF-8");} catch (Exception e) {LoggerUtil.logError(this.getClass().getName(), "getResult", e);return "";}}}
過濾器如下:
package com.paic.egis.smts.toa.web.filter;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletResponse;import com.alibaba.dubbo.common.utils.StringUtils;import com.paic.egis.smts.common.util.LoggerUtil;import com.paic.egis.smts.common.util.PropertiesUtil;import com.paic.egis.smts.pama.security.Base64Utils;import com.paic.egis.smts.toa.web.interceptor.ResponseWrapper;import com.paic.egis.smts.trusteesship.util.RSACoder;public class ResponseWrapperFilter implements Filter {public void destroy() {}public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {String version = req.getParameter("version");if(StringUtils.isEmpty(version)){chain.doFilter(req, resp);} else {HttpServletResponse response = (HttpServletResponse) resp;ResponseWrapper mr = new ResponseWrapper(response);chain.doFilter(req, mr);PrintWriter out = resp.getWriter(); try {//取返回的json串String result = mr.getResult(); System.out.println(result);//加密String encryptStr = encryptRSA(result);out.write(encryptStr); } catch (Exception e) {LoggerUtil.logError(this.getClass().getName(), "doFilter", e);} finally {out.flush(); out.close(); }}}@Overridepublic void init(FilterConfig filterconfig) throws ServletException {}//rsa公開金鑰加密public String encryptRSA(String content) throws Exception{String publicKeyStr = PropertiesUtil.getProperty("response.publicKey");byte[] encryptBytes = RSACoder.encrypt(content.getBytes("utf-8"), publicKeyStr,"public");return Base64Utils.encode(encryptBytes);}}
通過HttpServletResponseWrapper修改response輸出資料流