2

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

  • 一个简单的“登录”POJO 类
  • 一个实现spring接口的'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)

下面的代码截图。

  1. 登录.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;
        }
    
    }
    
  2. 登录验证器.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;        
        }   
    
    }
    
  3. 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(){
    
        }
    }
    
4

2 回答 2

5

第一的

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

应该

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

否则你的目标对象ErrorsLoginValidator对象而不是你的Login对象。

注意javadocErrors#rejectValue(..)

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

所以你在这里指定的

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

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

于 2014-03-08T16:58:50.043 回答
-1

查看您的堆栈跟踪,很可能您在类“LoginValidator”中的“登录”属性没有声明 Get 和 Set 方法,或者这些方法可能没有正确编写。

尝试在属性“login”中包含 Get/Set 方法,或者更正旧的方法以返回正确的对象类型,当然都是在“LoginValidator”类中。

于 2014-03-08T17:03:42.680 回答