简体   繁体   中英

Can Spring set the values of a @RequestBody in a generic controller?

I have a generic controller with a create() method mapping POST requests using some generic classes. I have created a subclass of that controller which provides the specific service and DTO types.

In theory, the subclass controller should not need to implement its own create() method. I have found, however, that if I don't implement a create() method in the subclass, the @RequestBody parameter is not getting properly set when I make requests.

Superclass

public abstract class GenericController<InputDtoClass, ModelClass> {
    @PostMapping
    public @ResponseBody ModelClass create(@Valid @RequestBody InputDtoClass input) {
        return service.create(input);
    }
}

Subclass

@RestController
@RequestMapping("/my/api/path")
public class SpecificController extends GenericController<SpecificInputDto, SpecificModel> {

}

What I expect is that when I call POST /my/api/path with some data, then my program should call the create() method of the superclass, populate a SpecificInputDto object, then validate it.

The program is correctly calling the create() method of the superclass, and it's correctly trying to validate the input object according to the annotated fields within the SpecificInputDto class. But the input object itself is not getting any of those values set. (To clarify, if I remove the @Valid tag, I can see that an object of the correct type gets passed, with all fields null). This is especially weird given that the program seems to handle generically-typed query parameter classes just fine. It's just the field annotated with @RequestBody that's not getting populated, even though Spring appears to know what specific type it's supposed to be.

EDIT : If I change the generic controller to use the specific InputDto type, it also fails to populate. But the same exact method, copied into the subclass, works correctly.

Apparently, every time I've used VSCode's autocompletion to import @RequestBody , it has decided to import io.swagger.v3.oas.annotations.parameters.RequestBody instead of org.springframework.web.bind.annotation.RequestBody .

Importing the correct RequestBody class fixed the issue for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM