0

I have to make GET method with a DTO. But when I code like this↓, an error occurs. org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'param' for method parameter type SampleDTO is not present

After checking that error, I figured out I need add option @RequestParam(required=false). Then, I restarted tomcat. Although there was no more error, my param was null(I actually sent sample_name). enter image description here

And I tried to use both of no annotation and @ModelAttribute. Both of them occurs same error↓ Caused by: java.lang.NoSuchMethodError: org.springframework.beans.BeanUtils.getResolvableConstructor(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;

What should I do? plz give me advice. I don't know best way handling DTO. Because I usually coded using HashMap actually.

Here is my example code.

//Controller sample
point: insertSample method works well.

@RestController
@RequestMapping("/sample")
public class SampleController {

    @Autowired
    private SampleService sampleService;

    @GetMapping
    public Result getSampleList(@RequestParam SampleDTO param) throws Exception {
        // (@RequestParam(required=false) SampleDTO param)
        // (@ModelAttribute SampleDTO param)
        // (SampleDTO param)
        return sampleService.getFolderList(param);
    }

    @PostMapping
    public Result insertSample(@RequestBody SampleDTO param) throws Exception {
        return sampleService.insertFolder(param);
    }
}

// DTO sample

@Getter // I didn't attach @Setter because of @Builder.
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@Alias("SampleDTO")
public class SampleDTO {

    @NotNull
    private Long sampleNo;

    @NotBlank
    private String sampleName;

    private String sampleDesc;

    @Builder
    public SampleDTO(Long sampleNo, String sampleName, String sampleDesc) {
        this.sampleNo = sampleNo;
        this.sampleName = sampleName;
        this.sampleDesc = sampleDesc;
    }

}
loveloper.dev
  • 299
  • 1
  • 4
  • 9
  • You need to use `@ModelAttribute` not `@RequestParam` and yo need to have setters else Spring will not be able to set the value. The name of the property (the setter) has to match the name of the parameter in your case with an `_` in between. – M. Deinum Aug 02 '22 at 07:28

2 Answers2

2

In order to bind request parameters to object you need to have standard getters/setters in your DTO class. Add @Setter to your method, then you can bind without even any annotation.

    @GetMapping
    public Result getSampleList(SampleDTO param) throws Exception {
        return sampleService.getFolderList(param);
    }
  • Thank you for answer! But I am still curious about its working. When I studied about DTO, people said "DTO should not have setter method.". So I didn't attached @ Setter on my SampleDTO. And actually, it worked well without @ Setter when I tested POST method(and @ RequestBody). Why is @ Setter necessary only specific case like GET method ? Could you tell me about it if you know the reason? – loveloper.dev Aug 02 '22 at 04:28
  • Reference for parameter binding: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-initbinder-model-design Reference for `@RequestBody`: https://stackoverflow.com/questions/70955984/why-requestbody-works-without-setters – Elyorbek Ibrokhimov Aug 02 '22 at 05:04
  • The GET uses binding, the POST uses serialization (in your code, not in general!) both are totally different mechanism. For binding (as mentioned int he Spirng documentation) you will need getters/setters else it won't work, **unless**, you configure direct field binding (instead of properties). – M. Deinum Aug 02 '22 at 07:32
0
@GetMapping
public Result getSampleList(@RequestParam("param") SampleDTO param) throws Exception {
    // (@RequestParam(required=false) SampleDTO param)
    // (@ModelAttribute SampleDTO param)
    // (SampleDTO param)
       return sampleService.getFolderList(param);
    }
}

Try like this, You should have to designate variable

  • Thank you for your answer. But it occus error -org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'param' for method parameter type SampleDTO is not present. – loveloper.dev Aug 02 '22 at 04:35
  • I agree with below answer, Because GET request does not use `Jackson2HttpMessageConverter`. `Jackson2HttpMessageConverter` serves to convert json data to Java objects. But It is relevant only POST reqeust. Because, GET is not JSON data, It is Query Parameter. So, If you want to use DTO in GET, You have to Add `@Setter` – SonYoonSeok Aug 02 '22 at 05:00
  • @SonYoonSeok both yoru answer as wella s your comment is wrong. It has nothing to do with a GET or POST request it has to do with how things are being send. A form/request parameters or as a http body. The first will use binding the second serialization (with `HttpMessageConverters`). – M. Deinum Aug 02 '22 at 07:30