th3an0maly
th3an0maly

Reputation: 3510

Spring - Instantiating an Errors object

I have a method like this:

public boolean validateMessage(String message, Errors errors) {
  if (!StringUtils.hasLength(message)) {
    errors.rejectValue(wrapperName + "message", "EMPTY_MESSAGE", EMPTY_MESSAGE_ERRORMSG) ;
            return false ;
        }
        return true ;
    }

I want to call this method with a new Errors object, like:

boolean result = validateMessage("hi", new Errors()) ;

However, this kind of instantiation is not allowed for Errors. Please advice.

If not with Errors, can I achieve this using an empty (new) BindingResult

Upvotes: 34

Views: 46711

Answers (7)

Most of times developers use @Valid and BindingResult to validate the posted or new object. For instance in the following code validates the Category object via @Valid annotation and then binds its result with BindingResult. But all these steps are done by Spring automatically.

@PostMapping
public String saveCategory(@Valid Category category, BindingResult bindingResult)
{
    // if there are some errors
    if (bindingResult.hasErrors())
    {
        for (ObjectError objectError : bindingResult.getAllErrors())
        {
            System.out.println(objectError.getDefaultMessage());
        }
    }

    ...
}

Although the above-mentioned code snippet is one of the outstanding advantages of Spring, occasionally you want the same behaviors in the other layers. So you must get an instance of implemented form of BindingResult and inject a Validator to your code:

...
import org.springframework.validation.Validator;
...

@Service
public class CategoryService
{

    @Autowired
    private Validator validator;
    ...

    private void insertNewCategory(Category category)
    {
        BindingResult bindingResult = new BeanPropertyBindingResult(category, "objectName");
        validator.validate(category, bindingResult);
        if(bindingResult.hasErrors())
        {
            for (FieldError fieldError : bindingResult.getFieldErrors())
            {
                System.out.println(fieldError.getDefaultMessage());
            }
        }
    ....
    }
}

Upvotes: 2

Anil Bhaskar
Anil Bhaskar

Reputation: 3978

First thing first, you can not initialize an object of Errors since this is an interface.

I am trying to initialize the Errors object for my JUnit test cases. There are many implementation available of Errors in Spring, (I have attached one picture below).

I tried new EscapedErrors(null), but it's constructor itself expects Errors object to be passed.

Solution: The constructor of org.springframework.validation.BeanPropertyBindingResult looks like below:

public BeanPropertyBindingResult(Object target, String objectName) {
        this(target, objectName, true, Integer.MAX_VALUE);
    }

So for me, Errors errors = new BeanPropertyBindingResult(new Object(), "dummy"); works like a charm.

enter image description here

Upvotes: 2

Ithar
Ithar

Reputation: 5465

If this is a Spring MVC application and you are using @Controllers you can pass your validation object in the form of org.springframework.validation.BindingResult as part of the mapping as such:

@RequestMapping(value="login.htm", method=RequestMethod.POST)
public String doLogin(HttpServletRequest request, Model model, BindingResult errors) {
    // ..... some validation code

    String message = "My message";
    boolean valid = validateMessage(message, errors); 

    // .... some more code
}

This is an alternative way of to having explicitly instantiating org.springframework.validation.Errors.

Upvotes: 1

Rober2D2
Rober2D2

Reputation: 588

Another option is to use org.springframework.validation.BeanPropertyBindingResult, which implements Errors. This object is of the same class of the BindingResult you recieve in Spring MVC controllers

Errors errors = new BeanPropertyBindingResult(objectToValidate, "objectName");

Upvotes: 22

Jonathan
Jonathan

Reputation: 20375

Errors and BindingResult are interfaces, therefore they cannot be instantiated. Your only option would be to use one of the classes which implements Errors.

You could use org.springframework.validation.BindException, this implements Errors - see here for details.

Upvotes: 23

Eric B.
Eric B.

Reputation: 24441

The method is expecting an Object which implements the Errors interface. Any class implementing the Errors interface would work. If you do not want to use an existing class such as org.springframework.validation.BindException, you can use an anonymous inner class. See the Spring Docs for existing classes which already implement Errors. But your anonymous class would need to implement all the interface methods, which are quite numerous and makes your code increasingly difficult to read:

boolean result = validateMessage( "hi", new Errors() {

        @Override
        public void setNestedPath(String nestedPath) {
            // TODO Auto-generated method stub

        }

        @Override
        public void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage) {
            // TODO Auto-generated method stub

        }

        @Override
        public void rejectValue(String field, String errorCode, String defaultMessage) {
            // TODO Auto-generated method stub

        }

        @Override
        public void rejectValue(String field, String errorCode) {
            // TODO Auto-generated method stub

        }

        @Override
        public void reject(String errorCode, Object[] errorArgs, String defaultMessage) {
            // TODO Auto-generated method stub

        }

        @Override
        public void reject(String errorCode, String defaultMessage) {
            // TODO Auto-generated method stub

        }

        @Override
        public void reject(String errorCode) {
            // TODO Auto-generated method stub

        }

        @Override
        public void pushNestedPath(String subPath) {
            // TODO Auto-generated method stub

        }

        @Override
        public void popNestedPath() throws IllegalStateException {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean hasGlobalErrors() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean hasFieldErrors(String field) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean hasFieldErrors() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean hasErrors() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public String getObjectName() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public String getNestedPath() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public List<ObjectError> getGlobalErrors() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public int getGlobalErrorCount() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public ObjectError getGlobalError() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Object getFieldValue(String field) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Class getFieldType(String field) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public List<FieldError> getFieldErrors(String field) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public List<FieldError> getFieldErrors() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public int getFieldErrorCount(String field) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public int getFieldErrorCount() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public FieldError getFieldError(String field) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public FieldError getFieldError() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public int getErrorCount() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public List<ObjectError> getAllErrors() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void addAllErrors(Errors errors) {
            // TODO Auto-generated method stub

        }
    } );

Upvotes: 0

user1710917
user1710917

Reputation:

you can instantiate class objects. but Errors is an interface, not a class. hence, it cannot be instantiated like you are trying to do.

Upvotes: 1

Related Questions