过滤器修改响应体导致前端JSON解析错误的解决方案
在使用过滤器修改HTTP响应体后,前端常常遇到JSON解析失败的问题。这是因为过滤器直接修改了原始响应数据,导致前端接收到的数据格式与预期不符。以下提供两种解决方法:
方法一:使用Jackson2ObjectMapperBuilderCustomizer自定义序列化器
如果问题源于long类型数据在JSON序列化过程中的差异,可以使用Jackson2ObjectMapperBuilderCustomizer注册自定义序列化器,将long类型转换为String类型输出。
@Configuration public class ObjectMapperConfig { @Bean public Jackson2ObjectMapperBuilderCustomizer longToStringSerializer() { return builder -> builder.serializerByType(Long.TYPE, new ToStringSerializer()); } }
方法二:使用ContentCachingResponseWrapper进行流式处理
ContentCachingResponseWrapper允许对响应体进行流式处理。 我们可以先缓存响应体,修改后再写入响应。
@Component @Slf4j public class LongTypeFilter extends OncePerRequestFilter { private final ObjectMapper objectMapper = new ObjectMapper(); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response); filterChain.doFilter(request, responseWrapper); String charset = responseWrapper.getCharacterEncoding(); String contentType = responseWrapper.getContentType(); if (contentType != null && contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) { byte[] responseBody = responseWrapper.getContentAsByteArray(); JsonNode rootNode = objectMapper.readTree(new String(responseBody, charset)); // 修改JsonNode,将long类型转换为String类型 (具体修改逻辑根据实际情况调整) convertLongToString(rootNode); String modifiedResponse = objectMapper.writeValueAsString(rootNode); byte[] modifiedBytes = modifiedResponse.getBytes(charset); responseWrapper.resetBuffer(); responseWrapper.setContentType(contentType + ";charset=" + charset); responseWrapper.setContentLength(modifiedBytes.length); responseWrapper.getWriter().write(modifiedResponse); } responseWrapper.copyBodyToResponse(); } private void convertLongToString(JsonNode node) { if (node.isContainerNode()) { node.fieldNames().forEachRemaining(fieldName -> convertLongToString(node.get(fieldName))); } else if (node.isLong()) { // 将long类型转换为String类型 ((ObjectNode) node.getParent()).put(node.fieldNames().next(), node.asText()); } } }
请注意,convertLongToString 方法需要根据你的实际JSON结构进行调整,以正确地找到并转换long类型的值。 选择哪种方法取决于你的具体需求和错误原因。 如果问题不是long类型导致的,你需要仔细检查过滤器修改响应体的逻辑,确保修改后的JSON格式正确。