package com.ruoyi.common.filter; import cn.hutool.json.JSONObject; import com.ruoyi.common.utils.Sm4Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.util.ContentCachingResponseWrapper; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.rmi.ServerException; public class SmCryptoFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(SmCryptoFilter.class); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; try { // 对请求进行解密 String decryptedRequestBody = decryptRequest(httpRequest); // 处理解密后的请求体 CustomRequestWrapper为自定义请求包装器,请看下面实现 CustomRequestWrapper customRequestWrapper = new CustomRequestWrapper(httpRequest, decryptedRequestBody); // 继续处理请求 ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(httpResponse); chain.doFilter(customRequestWrapper, responseWrapper); // 获取并加密响应内容 byte[] content = responseWrapper.getContentAsByteArray(); String originalResponseBody = new String(content); String encryptedResponseBody = encryptResponse(originalResponseBody); responseWrapper.setContentType("application/json"); JSONObject result = new JSONObject(); result.put("data", encryptedResponseBody); result.put("code", 200); // 设置返回编码 responseWrapper.setCharacterEncoding("UTF-8"); // 写回客户端 responseWrapper.reset(); responseWrapper.getWriter().write(result.toString()); responseWrapper.copyBodyToResponse(); } catch (Exception e) { logger.error("内部响应错误:{}", e.getMessage()); e.printStackTrace(); // 返回标准错误响应 httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); httpResponse.getWriter().write("Internal Server Error"); } } /** * 解密 HTTP 请求的主体内容。 * * @param request HTTP 请求对象 * @return 解密后的请求体字符串 * @throws IOException 如果读取或解密过程中发生错误 */ private String decryptRequest(HttpServletRequest request) throws IOException { StringBuilder jb = new StringBuilder(); String line; BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) { jb.append(line); } try { return Sm4Utils.sm4DecryptUtil(jb.toString()); } catch (Exception e) { throw new ServerException("参数解密失败:{}", e); } } /** * 加密 HTTP 响应的主体内容。 * * @param response 原始响应体字符串 * @return 加密后的响应体字符串 */ private String encryptResponse(String response) throws ServerException { try { return Sm4Utils.sm4EncryptUtil(response); } catch (Exception e) { throw new ServerException("参数解密失败:{}", e); } } }