Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping all request params into an object in Spring Controller [duplicate]

So, url requested looks like

localhost:8080/contacts?id=22&name=John&eventId=11

and also I got an object to map request into

public class ContactDTO {
    private Long id;
    private String name;
    private Long eventId;
}

I use a controller method like passing my request params into an object

@GetMapping("/contacts")
public ContactDTO contacts(ContactDTO contact) {
    // everything is awesome! contact maps clearly
    return contact;
}

The question is how to map like this but have different name

    localhost:8080/contacts?id=22&name=John&event_id=11

Setting @JsonAttribute doesn't works because Jackson mapper works only in requestbody. Maybe I should write custom HandlerMethodArgumentResolver or something like that?

P.S. I've got a dirty hack (objectMapper is injected, so I can use @JsonAttributes), But this case fails on array mapping, same mapping with requestbody works fine

@GetMapping("/contacts")
public ContactsDTO contacts(@RequestParam Map<String,String> params) {
    ContactDTO contactDTO = objectMapper.convertValue(params,ContactDTO.class);
    return contactDTO;
}
like image 637
Ivan Avatar asked May 23 '26 05:05

Ivan


1 Answers

Since it is an API design requirement, it should be clearly reflected in the corresponding DTO's and endpoints.

Usually, this kind of requirement stems from a parallel change and implies that the old type queries will be disabled during the contract phase.

You could approach the requirement by adding the required mapping "query-parameter-name-to-property-name" by adding it to the ContactDTO. The simplest way would be just to add an additional setter like below

public class ContactDTO {
    private Long id;
    private String name;
    private Long eventId;

    public void setEvent_id(Long eventId) {
        this.eventId = eventId;
    }
}

If you prefer immutable DTO's, then providing a proper constructor should work as well

@Value
public class ContactDTO {
    private Long id;
    private String name;
    private Long eventId;

    public ContactDTO(Long id, String name, String eventId, String event_id) {
        this.id = id;
        this.name = name;
        this.eventId = eventId != null ? eventId : event_id;
    }
}
like image 53
alexmagnus Avatar answered May 24 '26 17:05

alexmagnus