问题
I have a simple controller with method test:
@RequestMapping(produces = "application/json")
@ResponseBody
public HttpEntity<Void> test(Test test) {
return new ResponseEntity<>(HttpStatus.OK);
}
Test class looks like this:
public class Test {
private String name;
private Date date;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
@DateTimeFormat(iso= DateTimeFormat.ISO.DATE)
public void setDate(Date date) {
this.date = date;
}
}
And I need default values for fields of Test object. If I had a primitive param, I would be able to use @RequestParam(required = false, defaultValue = "someValue"). But with non-primitive param this approach doesn't seem to work. I see a couple of variants how to deal with it:
- Assign values in a constructor. Not very good, because may be I will need different defaults for different methods.
- Write custom DataBinder. Better, but the problem with different defaults still exists.
- Write custom DataBinder and custom annotation with defaults.
Am I missing something and there is a built in feature which can solve my problem?
回答1:
You can lean on argument resolving, in four easy steps, similiar as you suggested in your third point.
- Create an annotation e.g.
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestDefaultValues {
String[] value();
}
- Write a resolver e.g.
public class TestArgumentResolver implements HandlerMethodArgumentResolver {
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(TestDefaultValues.class) != null;
}
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
TestDefaultValues attr = parameter.getParameterAnnotation(TestDefaultValues.class);
String[] value = attr.value();
Test test = new Test();
test.setName(value[0]);
test.setDate(new Date(value[1]));
return test;
}
}
- register a resolver
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="your.package.TestArgumentResolver"></bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
- use an annotation in your controller method e.g.
public HttpEntity<Void> test(@TestDefaultValues({"foo","11/12/2014"}) Test test) {
instantiating date is just to get the gist of the implementation, obviously you'll use whatever is your idea
来源:https://stackoverflow.com/questions/29469887/spring-mvc-default-values-for-fields-of-method-parameter