Thanos M
Thanos M

Reputation: 673

Spring Rest - bind nested DTO object to @RequestParams

I want to bind get params to my DTO. My problem is mapping the nested list my DTO has.

controller class:

@PostMapping(value = "test-endpoint")
public ResponseEntity<String> doStuff(@Valid @RequestParams MyDto myDto) {
    // do stuff
}

parent DTO:

public class MyDto {
    @NotNull
    private String fieldA;

    @Valid
    @NotNull
    private List<MyNestedDto> nestedDto;
}

Nested DTO:

public class MyNestedDto {
    @NotNull
    private String nestedFieldA;

    @NotNull
    private String nestedFieldB;

    // more fields
}

I have a service that sends a POST request to my controller. The request cannot be changed hence why I can't use @RequestBody annotation.

The request looks like that:

http://localhost:8080/api/test-endpoint?nestedDto={"more":[{"nestedFieldA":"example","nestedFieldB":"example"}]}&fieldA=123

Is there a way to bind the nested list to get params?

Edit*

Registering a converter doesn't seem to work, my converter convert method is not even called.

@Configuration
public class WebConfiguration implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new MyConverter());
    }
}

public class MyConverter implements Converter<String, MyDto> {

    @Override
    public MyDto convert(String source) {
        // it never reaches there
        ObjectMapper objectMapper = new ObjectMapper();
        
        return null; // return null for testing purposes
    }
}

Upvotes: 0

Views: 1458

Answers (1)

Gurkan İlleez
Gurkan İlleez

Reputation: 1573

public class AController {
     private final ObjectMapper objectMapper;
     private final Validator validator;

     public AController(ObjectMapper objectMapper,Validator validator){
          this.objectMapper = objectMapper;
          this.validator = validator;
     }

     @PostMapping(value = "test-endpoint")
     public ResponseEntity<String> doStuff(@RequestParam("nestedDto") String nestedDto) {
           MyDto myDto = objectMapper.readValue(nestedDto);
           Set<ConstraintViolation<MyDto>> constraintViolation = 
           validator.validate(myDto);
           if (!constraintViolation.isEmpty()) {
                throw new ConstraintViolationException(constraintViolation);
           }
     }

}

This is pseudo code so i just write it to demonstrate how to solve the problem. If you want more elegant way, you have to change request because request is wrong here.

Upvotes: 1

Related Questions