Условное сопоставление запросов JSON при загрузке Spring - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть запрос на публикацию с URL http://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 

В дополнение к сопоставлению у меня также есть проверка Jsr303 внутри класса моей модели, поэтому я также хочу использовать @Допустимая аннотация Как мне сделать это

Ответы [ 3 ]

0 голосов
/ 05 ноября 2019

Я думаю, что это более простое решение:

@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");
    }

}
0 голосов
/ 06 ноября 2019

Я не уверен, почему выше ответы объясняют валидаторы. насколько я понимаю, вы пытаетесь вернуть два типа ответов в зависимости от условия. это невозможно. потому что возвращаемый тип проверяется во время компиляции. поэтому, если вы установите тип возвращаемого значения как classA, вы должны вернуть classA. вы не можете вернуть classB. (если classB не является отношением classA), поэтому, если вы действительно хотите это сделать, вы можете использовать интерфейс имен для принудительного применения типа.

@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));
        }
    }

PS: вам может потребоваться вернуть это значение как

public ResponseEntiry<Response>

но я только что использовал Response напрямую.

теперь вам нужно создать эти два класса из одного интерфейса

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

таким образом вы сможете достичь того, что вы естьпробовать.

0 голосов
/ 05 ноября 2019

Вы можете получить полезную нагрузку как 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");
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...