Spring引导中的条件JSON请求映射



我有一个带有URLhttp://my-custom-url/{param}的发布请求

现在

//pseudo code
if param == param1
then request body must be mapped to model Class A
if param == param2
then request body must be mapped to model Class B 

除了映射,我的模型类es中还有Jsr303验证,因此我也想使用@Valid注释我该如何进行

您可以接收作为Map<K, V>的有效载荷,并使用ObjectMapper对其进行反序列化。

@RestController
@RequestMapping(path = "/my-rest-api")
public class MyController {
@Autowired
ClassAValidator classAValidator; // assuming you wrote an validator
@Autowired
ClassBValidator classBValidator; // assuming you wrote an validator
@PostMapping("/{parameter}")
public ResponseEntity<Object> handleRequest(
@PathVariable("parameter") String parameter,
@RequestBody Map<Object, Object> request,
BindingResult result) {
ObjectMapper mapper = new ObjectMapper();
if (parameter.equals("X")) {
ClassA classA = mapper.convertValue(request, ClassA.class);
classAValidator.validate(classA, result);
if(result.hasErrors()) {
throw new CustomException(result);
}
} else if (parameter.equals("Y")) {
ClassB classB = mapper.convertValue(request, ClassB.class);
classBValidator.validate(classB, result);
if(result.hasErrors()) {
throw new CustomException(result);
}
} else {
// ..
}
return ResponseEntity.ok("Ok");
}
}

我认为这是一个更简单的解决方案:

@RestController
@RequestMapping("/my-custom-url")
public class MyController {
@PostMapping("/param1")
public ResponseEntity<Object> handleClassA(
@Valid @RequestBody ClassA classA,
BindingResult result) {
...
return ResponseEntity.ok("Ok");
}
@PostMapping("/param2")
public ResponseEntity<Object> handleClassB(
@Valid @RequestBody ClassB classB,
BindingResult result) {
...
return ResponseEntity.ok("Ok");
}
}

我不知道为什么上面的答案解释了验证器。据我所知,您正试图根据条件返回两种类型的响应。这是不可能的。因为返回类型在编译时验证。所以如果您将返回类型设置为classA,则必须返回classA。不能返回classB。(除非classB是classA关系(,所以如果您真的想这样做,您可以使用name接口来强制类型。

@GetMapping(value = "/{id}")
public Response getRent(@PathVariable int id, @RequestParam(required = false) String type) {
if(type=="A"){
return  new ClassA(rentService.findById(id));
}else{
return    new ClassB (rentService.findDetailResponse(id));
}
}

p.S:您可能需要将此作为退回

public ResponseEntiry<Response>

但我只是直接使用了Response。

现在您需要从同一个接口创建这两个类

public interface Response {
}
public class ClassA implements Response {
// your code goes here
}
public class ClassB implements Response {
// code here
}

这样你就可以实现你正在努力的目标。

最新更新