不可变类作为查询参数持有者 - Spring MVC

时间:2016-06-03 11:42:10

标签: java spring spring-mvc

我想让我的查询param类不可变(通过构造函数设置公共final字段)。有没有办法通过构造函数强制执行SearchQueryParam实例创建,并且不暴露可怕的getter / setter?

以下是有效的示例代码:

@RequestMapping(value = "/search", method = GET, produces = APPLICATION_JSON_VALUE)
public List<Result> search(SearchQueryParam searchQueryParam) {
        //do stuff;
}


public class SearchQueryParam {
    @DateTimeFormat(iso = DATE_TIME)
    private DateTime from;
    @DateTimeFormat(iso = DATE_TIME)
    private DateTime to;

    public DateTime getFrom() {
        return from;
    }

    public void setFrom(DateTime from) {
        this.from = from;
    }

    public DateTime getTo() {
        return to;
    }

    public void setTo(DateTime to) {
        this.to = to;
    }
}

但我希望我的SearchQueryParam类看起来更像这样:

public final class SearchQueryParam {

    @DateTimeFormat(iso = DATE_TIME)
    public final DateTime from;
    @DateTimeFormat(iso = DATE_TIME)
    public final DateTime to;

    public SearchQueryParam(DateTime from, DateTime to) {
        this.from = from;
        this.to = to;
    }
}

2 个答案:

答案 0 :(得分:0)

请尝试以下代码

public final class SearchQueryParam {

@DateTimeFormat(iso = DATE_TIME)
private final DateTime from;
@DateTimeFormat(iso = DATE_TIME)
private final DateTime to;

public SearchQueryParam(DateTime from, DateTime to) {
    this.from = from;
    this.to = to;
}

public DateTime getFrom() {
    return this.from;
}

public DateTime getTo() {
    return this.to;
}

}

以下几条评论将帮助您了解使课程成为不可变的步骤

  • 无需克隆输入的DateTime参数 (假设你使用的是Joda库,如果Joda DateTime对象是不可变的,你不需要克隆它们)
  • 制作,作为最终字段,以便只能从构造函数
  • 设置

答案 1 :(得分:0)

您可以使用WebArgumentResolver。 所有你必须写下自己的解析器

public class MySpecialArgumentResolver implements WebArgumentResolver {

   public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
     if (methodParameter.getParameterType().equals(MySpecialArg.class)) {
       return new MySpecialArg("myValue");
     }
     return UNRESOLVED;
   }
 }

之后你需要在春天注册这个解析器

<mvc:annotation-driven>
<mvc:argument-resolvers>
    <bean id="mySpecialArgumentResolver" class="..MySpecialArgumentResolver ">
    </bean>            
</mvc:argument-resolvers>

您可以阅读Use immutable objects in your Spring MVC controller by implementing your own WebArgumentResolver了解更多详情。在这篇文章中使用了旧样式,在3.1之后,他们添加了HandlerMethodArgumentResolver并且你可以使用它。此处为新版本stackoverflow post

的示例