我正在通过Spring MVC创建一个基本的登录页面。到目前为止,我已经创建了以下内容:


一个简单的“登录” POJO类
实现弹簧接口的'LoginValidator'类:org.springframework.validation.Validator
'LoginValidatorTests'类


我的单元测试失败,但出现以下异常:

org.springframework.beans.NotReadablePropertyException: Invalid property 'login' of bean class [springapp.service.LoginValidator]: Bean property 'login' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:707)
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:699)
    at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
    at org.springframework.validation.AbstractBindingResult.rejectValue(AbstractBindingResult.java:105)
    at springapp.service.LoginValidator.validateUsername(LoginValidator.java:44)
    at springapp.service.LoginValidator.validate(LoginValidator.java:27)
    at springapp.service.LoginValidatorTests.testEmptyUsernameAndPassword(LoginValidatorTests.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at junit.framework.TestCase.runTest(TestCase.java:164)
    at junit.framework.TestCase.runBare(TestCase.java:130)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:120)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


下面的代码片段。


Login.java:

软件包springapp.service;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class Login{

    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());

    private String username;
    private String password;

    public void setUsername(String username){
        this.username = username;
    }

    public String getUsername(){
        return username;
    }

    public void setPassword(String password){
        this.password = password;
    }

    public String getPassword(){
        return password;
    }

}

LoginValidator.java

package springapp.service;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

//import springapp.domain.Login;

public class LoginValidator implements Validator {

    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());

    public boolean supports(Class clazz) {
        return Login.class.equals(clazz);
    }

    public void validate(Object obj, Errors errors) {
        Login login = (Login) obj;

        if (login == null) {
            errors.rejectValue("login", "error.username-and-password-required", null, "Value required.");
        }
        //validate username
        validateUsername(login, errors);

        //if no errors, validate password
        if (!errors.hasErrors()){
            validatePassword(login, errors);
        }
    }

    private boolean validateUsername(Login login, Errors errors){
        String username = login.getUsername();

        if (username == null || username.length() == 0){
            errors.rejectValue("login", "error.username-required", null, "Value required.");
            return false;
        }

        if (username != "admin") {
            errors.rejectValue("login", "error.username-not-found", null, "Value required.");
            return false;
        }

        return true;
    }

    private boolean validatePassword(Login login, Errors errors){
        String password = login.getPassword();

        if (password == null || password.length() == 0){
            errors.rejectValue("login", "error.password-required", null, "Value required.");
            return false;
        }

        if (password != "admin") {
            errors.rejectValue("login", "error.password-invalid", null, "Value required.");
            return false;
        }

        return true;
    }

}

LoginValidatorTests.java。运行单元测试“ testEmptyUsernameAndPassword”时,出现异常:

package springapp.service;

import junit.framework.TestCase;

import springapp.service.LoginValidator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Validator;
import org.springframework.validation.Errors;

public class LoginValidatorTests extends TestCase {

    protected final Log logger = LogFactory.getLog(getClass());
    private LoginValidator loginValidator = new LoginValidator();
    private Login login= new Login();
    private Errors errors = new BeanPropertyBindingResult(loginValidator, "loginValidator");

    public void testEmptyUsernameAndPassword(){
        login.setPassword("ee");
        login.setUsername("ee");
        loginValidator.validate(login, errors);

        assertTrue(errors.hasErrors());
        //assertTrue(errors.getFieldError().toString().contains("error.username-and-password-required"));
    }

    public void testEmptyUsernameOnly(){

    }

    public void testEmptyPasswordOnly(){

    }

    public void testInvalidUsername(){

    }

    public void testInvalidPassword(){

    }
}

最佳答案

第一

private Errors errors = new BeanPropertyBindingResult(loginValidator, "loginValidator");


应该

private Errors errors = new BeanPropertyBindingResult(login, "login" /* or whatever name */);


否则,Errors的目标对象是LoginValidator对象,而不是Login对象。

注意Errors#rejectValue(..)的javadoc


  field-字段名称(可以为null或为空字符串)


所以你在这里指定

errors.rejectValue("login", "error.username-required", null, "Value required.");


login实际上用作目标对象的类的字段名称。但是您的Login类和LoginValidator类都没有这样的字段。您应该在适当的地方使用usernamepassword

07-25 22:43