【问题标题】:Mapping all request params into an object in Spring Controller [duplicate]将所有请求参数映射到 Spring Controller 中的对象 [重复]
【发布时间】:2020-03-14 20:52:54
【问题描述】:

所以,请求的 url 看起来像

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

我还有一个对象可以将请求映射到

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

我使用控制器方法,例如将请求参数传递给对象

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

问题是如何像这样映射但名称不同

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

设置 @JsonAttribute 不起作用,因为 Jackson 映射器仅在 requestbody 中起作用。 也许我应该编写自定义 HandlerMethodArgumentResolver 或类似的东西?

附: 我有一个肮脏的黑客(objectMapper 被注入,所以我可以使用@JsonAttributes), 但是这种情况在数组映射上失败了,与 requestbody 相同的映射工作正常

@GetMapping("/contacts")
public ContactsDTO contacts(@RequestParam Map<String,String> params) {
    ContactDTO contactDTO = objectMapper.convertValue(params,ContactDTO.class);
    return contactDTO;
}

【问题讨论】:

  • 将映射更改为Post 并创建一个QueryDto (for example) 并以您想要的方式使用它。恕我直言,使用 json 会更好,并且可以挽救您的生命。
  • 你在创建 Rest API 吗?
  • @emotionlessbananas 我知道如何在 POST 中轻松做到这一点,但现在我必须在 GET 中做到这一点
  • @Satheeshkumar No
  • @AritraPaul No.

标签: java spring spring-boot jackson jackson-databind


【解决方案1】:

既然是API设计要求,就应该在对应的DTO和endpoints中明确体现出来。

通常,这种要求源于parallel change,并暗示旧类型查询将在合同阶段被禁用。

您可以通过将所需的映射“query-parameter-name-to-property-name”添加到ContactDTO 来满足要求。最简单的方法就是添加一个额外的设置器,如下所示

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

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

如果您更喜欢不可变的 DTO,那么提供适当的构造函数也应该可以工作

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

【讨论】:

    【解决方案2】:

    使用类似的东西

    @RequestParam(name="event_id", required = true) long eventId
    

    在参数列表中更改参数名称。

    【讨论】:

    • 我知道如何更改参数列表中的参数名称,但我没有参数列表!我的方法消耗了自动映射的DTO,请再次检查问题
    【解决方案3】:

    使用@RequestBody 代替@requestparam。

    【讨论】:

    • 是GET方式,所有request prams在query url中发送
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 2020-02-10
    • 2023-04-04
    相关资源
    最近更新 更多