3

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?

2
  • 1
    Why can't you assign the default value in the method itself, after checking it is null? Commented Apr 6, 2015 at 11:00
  • It's not very convenient. In each method where I have defaults I need to write some ifs and assignments. While with primitive types it is handled via annotation. Commented Apr 6, 2015 at 11:52

1 Answer 1

1

You can lean on argument resolving, in four easy steps, similiar as you suggested in your third point.

  1. Create an annotation e.g.

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestDefaultValues {
    String[] value();
}
  1. 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;
    }

}
  1. register a resolver

<mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="your.package.TestArgumentResolver"></bean>
        </mvc:argument-resolvers>
</mvc:annotation-driven>
  1. 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

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer. It is better, but still we tied to Test class. I hoped there is a generic annotation for this purpose in Spring, but it seems like there is not.
You welcome. In fact, depending on your needs, but you can use this approach and make it more generic, note that the resolveArgument method returns Object. For example you can use the following signature (@TestDefaultValues({"foo","11/12/2014", "test"}) Object test) and than in the resolver class use the additional annotation parameter to figure out which class you're instantiating, and other annotation params to populate the default values. Anyways the only thing that matters is that you know the construct, you'll decide if you can use it for what you're trying to achieve

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.