Reputation: 3510
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
Reputation: 3675
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
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.
Upvotes: 2
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
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
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
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
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