【问题标题】:Spring 4 MVC - Rest service - use default values in beansSpring 4 MVC - 休息服务 - 在 bean 中使用默认值
【发布时间】:2016-05-31 16:30:40
【问题描述】:

我正在使用Spring 4.1.4 并实现一个简单的REST 服务。我确实有一个POST 方法,它获取一个Person 对象作为请求。

@ResponseStatus(value = HttpStatus.CREATED)
@RequestMapping(value = "", method = RequestMethod.POST, headers = "Accept=application/json", consumes = "application/json")
public void add(@Valid @RequestBody Person oPerson) throws Exception {
    //do the things
}

豆:

public class Person {

    public Person(){ }

    private String firstname;

    private String lastname;

    private Integer activeState;

    //getter+setter
}

我的问题是 - 是否有可能为 bean 中的属性设置默认值。像这样的:

@Value(default=7)
private Integer activeState;

我知道在@RestController 方法中使用@RequestParam 注释时,可以使用@RequestParam(value="activeState", required=false, defaultValue="2") 设置默认值,但是否有可能在类级别上做类似的事情?

【问题讨论】:

  • 什么时候应该应用默认值:如果参数根本不在请求中,或者参数是否为空/空?
  • 只需为类中的整数字段声明一个值:private Integer activeState = 2; 还是我误会了你?
  • @Ralph 好问题 - 在这两种情况下:不存在和 null 或空
  • @RobinJonsson - 我也想过这个问题,但我不知道这是否是最好的解决方案,我也将该对象用作数据库的持久性对象...
  • @K.E.我一直有不使用我的实体一直到前端的心态。但是,只要传入对象没有覆盖该字段,就可以像这样设置默认值。这不是你要找的吗?

标签: java spring rest spring-mvc spring-4


【解决方案1】:

添加到@Edd 答案,如果你想覆盖输入中的默认值,那么我们必须用@JsonAutoDetect 注释bean,如下所示:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;

@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class Person {

    public Person() {
    }

    private String firstName = "default";
    private String lastName = "default";
    private Integer activeState = 7;

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Integer getActiveState() {
        return activeState;
    }

    @Override
    public String toString() {
        return "Person{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", activeState=" + activeState +
                '}';
    }
}

【讨论】:

    【解决方案2】:

    您的 Person 类并不是真正的 spring bean。由于@RequestBody 注释,它只是一个在您调用应用程序端点时设置其参数的类。不在调用正文中的参数根本不会被绑定,因此要解决您的问题,您可以这样做:

    1. 像这样为您的人员类设置默认值(为方便起见,toString() 被覆盖:

      public class Person {
      
          public Person() {
          }
      
          private String firstName = "default";
          private String lastName = "default";
          private Integer activeState = 7;
      
          public String getFirstName() {
              return firstName;
          }
      
          public String getLastName() {
              return lastName;
          }
      
          public Integer getActiveState() {
              return activeState;
          }
      
          @Override
          public String toString() {
              return "Person{" +
                      "firstName='" + firstName + '\'' +
                      ", lastName='" + lastName + '\'' +
                      ", activeState=" + activeState +
                      '}';
          }
      }
      
    2. 对您的端点执行请求,例如使用此 json 数据:

      {
          "firstName": "notDefault"
      }
      
    3. 如果您在控制器中打印出 person 对象,您会注意到 firstName 获得了非默认值,而其他人则为默认值:

      public void add(@Valid @RequestBody Person oPerson) {
          System.out.println(oPerson);
      }
      

    控制台输出: Person{firstName='notDefault', lastName='default', activeState=7}

    【讨论】:

    • 很好,如果你的 dto 是不可变的呢?此外,我不认为 dto 对象有责任决定行为或控制器端点
    • @Ben 如果它们是不可变的,则在控制器方法中处理默认值分配。也就是说,检查缺少哪些值,并为您的不可变对象创建一个新副本,并分配它们。
    • 当我们为多个端点使用相同的 DTO 时,这不是一个好案例。一些端点希望有不同的默认值或根本没有默认值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2015-04-01
    • 2012-02-15
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多