如何在WebClient Get请求中传递对象列表至Spring Get控制器
解决Spring GET控制器接收List参数并通过WebClient调用的问题
问题根源
- 原控制器方法未添加
@RequestParam注解,Spring无法识别并绑定List<Employee>类型的请求参数 - WebClient直接将
List<Employee>对象传入queryParam,无法被Spring解析为合法的GET请求参数格式 Employee类缺少必要的getter方法,Spring无法读取属性值完成参数绑定
修正步骤
1. 完善Employee类与控制器方法
先给Employee类添加getter方法,并修正控制器的参数注解:
// 完善Employee类 public class Employee { private String id; private String name; // 构造方法 public Employee(String id, String name) { this.id = id; this.name = name; } // 添加getter方法,Spring参数绑定依赖此方法 public String getId() { return id; } public String getName() { return name; } } // 修正控制器方法,添加@RequestParam注解指定参数名 @GetMapping("/demo") public List<Student> m1(@RequestParam("account") List<Employee> account) { // 业务逻辑处理 return new ArrayList<>(); }
2. 调整WebClient调用代码
Spring MVC支持通过索引式查询参数绑定对象列表,格式为account[0].id=xxx&account[0].name=xxx&account[1].id=xxx,WebClient需按此格式构造请求参数:
Employee e = new Employee("1", "tarun"); Employee e1 = new Employee("2", "run"); List<Employee> employeeList = new ArrayList<>(); employeeList.add(e); employeeList.add(e1); webclient.get() .uri(uriBuilder -> { UriComponentsBuilder builder = uriBuilder.path("/demo"); // 逐个拼接每个Employee的属性参数 for (int i = 0; i < employeeList.size(); i++) { Employee emp = employeeList.get(i); builder.queryParam("account[" + i + "].id", emp.getId()) .queryParam("account[" + i + "].name", emp.getName()); } return builder.build(); }) .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(new ParameterizedTypeReference<List<Student>>() {});
替代方案:序列化对象为字符串传递
如果不想拆分属性,可将每个Employee序列化为JSON字符串,作为多个account参数传递,控制器再反序列化为对象:
控制器调整:
@GetMapping("/demo") public List<Student> m1(@RequestParam("account") List<String> accountJsonList) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); List<Employee> account = accountJsonList.stream() .map(json -> { try { return objectMapper.readValue(json, Employee.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } }) .collect(Collectors.toList()); // 业务逻辑处理 return new ArrayList<>(); }
WebClient调整:
ObjectMapper objectMapper = new ObjectMapper(); webclient.get() .uri(uriBuilder -> { UriComponentsBuilder builder = uriBuilder.path("/demo"); for (Employee emp : employeeList) { try { builder.queryParam("account", objectMapper.writeValueAsString(emp)); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } return builder.build(); }) .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(new ParameterizedTypeReference<List<Student>>() {});
内容的提问来源于stack exchange,提问作者Tarun Singh
相关产品推荐
相关产品推荐

