向端点发送JSON失败:生成ArrayList后转发至指定端点求助
问题排查与解决方案
嘿,我来帮你搞定这个发送JSON失效的问题!先看你贴的createCustomer方法,首先就有个容易踩的坑,然后咱们一步步解决:
首先:修复集合的线程安全问题
你用了parallel()并发生成Customer对象,但是ArrayList不是线程安全的集合,并发添加元素的时候很容易出现元素丢失、重复,甚至直接抛出并发修改异常,这大概率是后续JSON发送失效的根源之一。给你两个修复方案:
方案1:换成线程安全的集合
直接把ArrayList包装成同步集合,代码改起来很简单:
@GetMapping("/createcustomer/{start}/{end}") @ResponseBody public List<Customer> createCustomer(@PathVariable int start, @PathVariable int end) { // 用同步包装类让ArrayList线程安全 List<Customer> customerList = Collections.synchronizedList(new ArrayList<>()); IntStream.range(start, end).parallel().forEach(index -> { customerList.add(generateCustomer()); }); // 后面加转发逻辑 return customerList; }
方案2:用Stream的collect方法(更推荐)
这种方式不用手动处理线程安全,Stream会帮你正确收集并发生成的元素,代码更简洁优雅:
@GetMapping("/createcustomer/{start}/{end}") @ResponseBody public List<Customer> createCustomer(@PathVariable int start, @PathVariable int end) { List<Customer> customerList = IntStream.range(start, end) .parallel() .mapToObj(i -> generateCustomer()) // Stream自动处理并发收集,避免线程安全问题 .collect(Collectors.toList()); // 后面加转发逻辑 return customerList; }
然后:实现转发到指定端点
生成好正确的客户列表后,你可以用Spring提供的RestTemplate(传统Spring MVC)或者WebClient(Spring 5+推荐,尤其是WebFlux场景)来发送JSON到目标端点:
用RestTemplate的示例(传统MVC项目)
首先得在Spring容器里注册RestTemplate的Bean:
@Bean public RestTemplate restTemplate() { return new RestTemplate(); }
然后在你的控制器里注入并使用:
@Autowired private RestTemplate restTemplate; @GetMapping("/createcustomer/{start}/{end}") @ResponseBody public ResponseEntity<String> createCustomer(@PathVariable int start, @PathVariable int end) { // 先生成线程安全的客户列表 List<Customer> customerList = IntStream.range(start, end) .parallel() .mapToObj(i -> generateCustomer()) .collect(Collectors.toList()); // 替换成你的目标端点URL String targetUrl = "http://your-target-api.com/customers"; try { // 发送POST请求,把customerList转成JSON发送 ResponseEntity<String> response = restTemplate.postForEntity(targetUrl, customerList, String.class); // 返回转发的结果给调用方 return ResponseEntity.status(response.getStatusCode()).body("转发成功:" + response.getBody()); } catch (RestClientException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("转发失败:" + e.getMessage()); } }
用WebClient的示例(WebFlux项目)
如果你的项目是基于响应式的WebFlux,推荐用WebClient:
@Bean public WebClient webClient() { return WebClient.create(); } @Autowired private WebClient webClient; @GetMapping("/createcustomer/{start}/{end}") public Mono<ResponseEntity<String>> createCustomer(@PathVariable int start, @PathVariable int end) { List<Customer> customerList = IntStream.range(start, end) .parallel() .mapToObj(i -> generateCustomer()) .collect(Collectors.toList()); String targetUrl = "http://your-target-api.com/customers"; return webClient.post() .uri(targetUrl) .contentType(MediaType.APPLICATION_JSON) .bodyValue(customerList) .retrieve() .bodyToMono(String.class) .map(body -> ResponseEntity.ok("转发成功:" + body)) .onErrorResume(e -> Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("转发失败:" + e.getMessage()))); }
最后:排查JSON序列化的潜在问题
如果前面的步骤都做了还是不行,得检查这几点:
Customer类有没有正确的getter/setter方法?Spring默认用Jackson序列化JSON,需要这些方法来读取对象属性。Customer类有没有无参构造函数?可以加个@NoArgsConstructor注解(Lombok的话),Jackson默认需要它来处理序列化/反序列化。- 目标端点能不能正确接收JSON数组?可以先用Postman手动发一个测试的Customer数组,确认端点本身没问题。
小提示:如果你的接口不需要把customerList返回给调用方,而是直接转发后返回结果,可以去掉
@ResponseBody,或者调整返回类型为转发的响应内容就行。
内容的提问来源于stack exchange,提问作者elp
相关产品推荐
相关产品推荐

