一次后台JSON解析报错分析
初看这个问题,以为是json 数据格式有问题,然后就投入到具体的json 数据分析中,只是这种事批量入库的,每次1000条,怎么定位到哪一条?这种数据都是文档分段后的内容,各种回车换行转义的,但是将数据拿到JSON 格式数据校验工具中格式化,直接返回 老铁,没毛病,格式正确。刚开始AI 看这个数据,就说是被截断,不完整,我理解是以为文档分段造成的语义不完整截断,然后就告诉AI 这个分段造成的,于是
一、场景
大模型功能需要计算向量,对数据进行向量化处理,在使用sdk接口进行批量处理向量操作时报错如下:
服务器异常syntax error, expect {, actual string, fieldName data, pos 315, line 1, column 316{"status":400,"code":400,"success":false,"data":"JSON parse error: Unexpected end-of-input in VALUE_STRING; nested exception is com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input in VALUE_STRING\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2563]","msg":"参数校验失败"}
二、问题分析
初看这个问题,以为是json 数据格式有问题,然后就投入到具体的json 数据分析中,只是这种事批量入库的,每次1000条,怎么定位到哪一条?然后就开始尝试减少每次插入的数量,试了几次最终才找到了一条记录,然后就开发分析这个数据。这种数据都是文档分段后的内容,各种回车换行转义的,但是将数据拿到JSON 格式数据校验工具中格式化,直接返回 老铁,没毛病,格式正确。
然后就有点开始傻眼了,于是就问AI 了。刚开始AI 看这个数据,就说是被截断,不完整,我理解是以为文档分段造成的语义不完整截断,然后就告诉AI 这个分段造成的,于是AI 又给了其他思路,反正从spring nginx 传统的http 传输大小限制开始,一路排查,最终都不对。
最终还是老老实实断点调试,发现问题点:

这里面传入过来的body 已经正常日志输出, 只是这个result调用返回的结果报错,所以这个json 数据原始的应该是没问题的,基于这个问AI , 就判断是请求中被filter 过滤了,然后给出了查看过滤器的方式:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.servlet.Filter;
import java.util.Map;
@Component
@Slf4j
public class FilterOrderPrinter {
@Autowired
private ApplicationContext context;
@PostConstruct
public void printFilters() {
Map<String, FilterRegistrationBean> beans =
context.getBeansOfType(FilterRegistrationBean.class);
beans.values().forEach(bean -> {
Filter filter = bean.getFilter();
int order = bean.getOrder();
log.info("Filter: {} , order={}",
filter.getClass().getName(), order);
});
}
}
最终定位到有三个过滤器, 其中有一个是封装了xss 过滤的, 联想到这些内容中确实有 <> 这种符号,于是将xss 过滤对于这个接口进行配置禁用,果然就正常了。

由于通过了xss 过滤,原始数据被截掉了,所以在接口通过json 结构转Map过程中就报错了:
@PostMapping("/v1/embeddings")
@ApiOperation(value = "向量计算")
@ApiOperationSupport(order = 1)
public Map<String,Object> embeddings(@RequestBody JSONObject body) {
String collectionName = body.getString("collectionName");
List<String> input = body.getJSONArray("input").toJavaList(String.class);
String embeddingSignage = body.getString("embeddingSignage");
return emBeddingService.embeddings(collectionName, input, embeddingSignage);
}
所以问题日志看到的都是后续副产品结果,真正的原因还是因为filter 在请求中对数据进行了过滤处理。
更多推荐


所有评论(0)