【问题标题】:Play Framework - How to map web data to object dataPlay Framework - 如何将 Web 数据映射到对象数据
【发布时间】:2015-11-28 15:26:50
【问题描述】:

想象以下场景:

我使用以下参数向服务(使用 Play 框架)发送请求(按惯例,参数名称应加下划线):

first_name=James&second_name=Parker

此外,我的代码库中有一个模型类,看起来像这样。

public class User {
    @Constraints.Required
    private String firstName;

    @Constraints.Required
    private String secondName;

    public String getFirstName() {
        return firstName;
    }

    public String getSecondName() {
        return secondName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public void setSecondName(String secondName) {
        this.secondName = secondName;
    }

}

我要做的就是将参数的名称与相应的 字段名称。以下使用 Play Framework 的语句失败,因为 用户对象不能用给定的请求参数初始化。

Form<User> form = Form.form(User.class).bindFromRequest();

【问题讨论】:

    标签: java data-binding playframework


    【解决方案1】:

    首先阅读:https://www.playframework.com/documentation/2.1.1/JavaRouting

    然后:

    GET    /myMethod/:firstName/:seccondName    controllers.MyController.myMethod(firstName: String, seccondName: String)
    

    简单的方法:

    public myMethod(String firstName, String lastName) {
        User u = new User();
        u.setFirstName(firstName);
        u.setSeccondName(seccondName);
    }
    

    显然,如果您使用播放框架 2。

    【讨论】:

    【解决方案2】:

    您的请求参数名称中有下划线,但您的类中有驼峰式的成员(例如first_name vs fistName [此处缺少r])。

    其次,这些类成员似乎也被声明为私有,并且您没有设置方法,只有 getter(即 setFirstName)。

    为了进行绑定,您的类被实例化并设置了值,如果没有办法这样做,它将失败。

    一旦你解决了上述问题,你应该可以绑定然后调用form.hasErrors()来检查验证是否失败。

    希望对您有所帮助。

    更新:

    要处理请求参数名称和类成员名称之间的不匹配,您可能必须手动进行设置。

    在你的控制器方法中,你会做这样的事情:

    Map<String, String[]> reqBody = request().body().asFormUrlEncoded()
    Map<String, String[]> newReqBody = new HashMap<>();
    
    for(Map.Entry<String, String[]> entry: body.entrySet()) {
        newBody.put(underscoreToCamelCase(entry.key()), entry.value());
    }
    
    Form<User> form = Form.form(User.class).bindFromRequest(newReqBody);
    

    请注意,我使用的是 bindFromRequest 的重载版本,如 here 所示

    然后,您应该以足够通用的方式实现underscoreToCamelCase 方法来处理您的所有约定(也许您可能会遇到多个下划线的情况)。

    【讨论】:

    • 首先很抱歉,因为我的问题不是很清楚。我想按照惯例在请求参数中保留下划线,并且我想为 Java 字段保留 camelCase。因此,我想要的是下划线参数名称和对应的 Java 字段名称的自定义映射。
    • 我认为除非参数名称与类成员/字段匹配,否则您将无法免费获得自动绑定。您最好的选择是将请求映射手动转换为正确的格式。在答案中查看我的更新。
    • 感谢您的回答。这就是我的想法,但我正在寻找一种更优雅的方式来做到这一点。
    • 不确定您是否已经找到了优雅的解决方案,但是...我能想到的最好的方法是在全局级别进行与上述相同的映射(下划线为 camelCase)。这可以通过覆盖 Play 的全局设置中的onRequest 方法来完成(请参阅here)。至少这样你就不必在每个控制器方法中重复你自己了。
    猜你喜欢
    • 2011-04-24
    • 1970-01-01
    • 2012-07-18
    • 2023-04-06
    • 1970-01-01
    • 2022-10-02
    • 2020-06-26
    • 1970-01-01
    • 2021-09-22
    相关资源
    最近更新 更多