过滤器修改响应体导致前端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格式正确。