【问题标题】:SpringMvc java.lang.NullPointerException When Posting Form To ServerSpringMvc java.lang.NullPointerException 将表单发布到服务器时
【发布时间】:2012-09-24 03:27:18
【问题描述】:

当我跳出该字段时,我有一个带有用户名字段的表单,我使用 RESTFUL Web Service调用控制器中的处理程序方法。该方法调用 DAO 类来检查数据库是否存在用户名。

这很好用,但是当表单发布到服务器时,我调用了与处理程序方法中调用的完全相同的函数,但是当它访问类时我得到了一个 java.lang.NullPointerException调用 DAO 对象。所以它甚至不会第二次访问 DAO 对象。

我的所有调用类中的调用都有异常处理程序。关于这里发生的事情的任何想法为什么我会在第二次调用函数时得到 java.lang.NullPointerException。这与 Spring 实例化 有什么关系>DAO 类使用 Singleton 方法或类似的方法?可以做些什么来解决这个问题?

这是第一次使用 Web 服务调用方法时发生的情况(假设会发生):

13011 [http-8084-2] INFO  com.crimetrack.jdbc.JdbcOfficersDAO  - Inside jdbcOfficersDAO
13031 [http-8084-2] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL query
13034 [http-8084-2] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL statement [SELECT userName FROM crimetrack.tblofficers WHERE userName = ?]
13071 [http-8084-2] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Fetching JDBC Connection from DataSource
13496 [http-8084-2] DEBUG org.springframework.jdbc.core.StatementCreatorUtils  - Setting SQL statement parameter value: column index 1, parameter value [adminz], value class [java.lang.String], SQL type unknown
13534 [http-8084-2] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Returning JDBC Connection to DataSource
13537 [http-8084-2] INFO  com.crimetrack.jdbc.JdbcOfficersDAO  - No username was found in exception
13537 [http-8084-2] INFO  com.crimetrack.service.ValidateUserNameManager  - UserName :adminz does NOT exist

当表单是“发布”并且验证方法第二次处理表单并调用 Web 服务将调用的相同方法时:

17199 [http-8084-2] INFO  com.crimetrack.service.OfficerRegistrationValidation  - UserName is not null so going to check if its valid for :adminz
17199 [http-8084-2] INFO  com.crimetrack.service.OfficerRegistrationValidation  - User Name in try.....catch block is adminz
17199 [http-8084-2] INFO  com.crimetrack.service.ValidateUserNameManager  - Inside Do UserNameExist about to validate with username : adminz
17199 [http-8084-2] INFO  com.crimetrack.service.ValidateUserNameManager  - UserName :adminz EXCEPTION OCCURED java.lang.NullPointerException

ValidateUserNameManager.java

public class ValidateUserNameManager implements ValidateUserNameIFace {

    private OfficersDAO officerDao;

    private final Logger logger = Logger.getLogger(getClass());


    public boolean DoesUserNameExist(String userName) throws Exception {

        logger.info("Inside Do UserNameExist about to validate with username : " + userName);

        try{

            if(officerDao.OfficerExist(userName) == true){

                logger.info("UserName :" + userName + " does exist");
                return true;

            }else{
                logger.info("UserName :" + userName + " does NOT exist");
                return false;
            }


        }catch(Exception e){

            logger.info("UserName :" + userName + " EXCEPTION OCCURED " + e.toString());
            return false;
        }       

    }

    /**
     * @return the officerDao
     */
    public OfficersDAO getOfficerDao() {
        return officerDao;
    }

    /**
     * @param officerdao the officerDao to set
     */
    public void setOfficerDao(OfficersDAO officerDao) {
        this.officerDao = officerDao;
    }



}

JdbcOfficersDAO.java

public boolean OfficerExist(String userName){

    String dbUserName;

    try{

        logger.info("Inside jdbcOfficersDAO");


        String sql = "SELECT userName FROM crimetrack.tblofficers WHERE userName = ?";

        try{
            dbUserName = (String)getJdbcTemplate().queryForObject(sql, new Object[]{userName},String.class);
            logger.info("Just Returned from database");

        }catch(Exception e){
            logger.info("No username was found in exception");
            return false;
        }

        if(dbUserName == null){

            logger.info("Database did not find any matching records");
        }

        logger.info("after JdbcTemplate");

        if (dbUserName.equals(userName)) {

            logger.info("User Name Exists");
            return true;

        }else{
            logger.info("User Name Does NOT Exists");
            return false;
        }       

    }catch(Exception e){

        logger.info("Exception Message in JdbcOfficersDAO is "+e.getMessage());
        return false;
    }
}

OfficerRegistrationValidation.java

public class OfficerRegistrationValidation implements Validator{

    private final Logger logger = Logger.getLogger(getClass());

    private ValidateUserNameManager validateUserNameManager;


    public boolean supports(Class<?> clazz) {

        return Officers.class.equals(clazz);
    }


    public void validate(Object target, Errors errors) {

        Officers officer = (Officers) target;

        if (officer.getUserName() == null){

            errors.rejectValue("userName", "userName.required");

        }else{

            String userName = officer.getUserName();                    

            logger.info("UserName is not null so going to check if its valid for :" + userName);
            try {

                logger.info("User Name in try.....catch block is " + userName);

                if (validateUserNameManager.DoesUserNameExist(userName)== true){

                    errors.rejectValue("userName", "userName.exist");
                }
            } catch (Exception e) {
                logger.info("Error Occured When validating UserName");
                errors.rejectValue("userName", "userName.error");
            }

        }

        if(officer.getPassword()== null){
            errors.rejectValue("password", "password.required");
        }

        if(officer.getPassword2()== null){
            errors.rejectValue("password2", "password2.required");
        }


        if(officer.getfName() == null){
            errors.rejectValue("fName","fName.required");
        }

        if(officer.getlName() == null){

            errors.rejectValue("lName", "lName.required");
        }

        if (officer.getoName() == null){
            errors.rejectValue("oName", "oName.required");
        }

        if (officer.getEmailAdd() == null){
            errors.rejectValue("emailAdd", "emailAdd.required");
        }

        if (officer.getDob() == null){
            errors.rejectValue("dob", "dob.required");
        }

        if (officer.getGenderId().equals("A")){
            errors.rejectValue("genderId","genderId.required");
        }


        if(officer.getDivisionNo() == 1){

            errors.rejectValue("divisionNo", "divisionNo.required");
        }

        if(officer.getPositionId() == 1){

            errors.rejectValue("positionId", "positionId.required");
        }

        if (officer.getStartDate() == null){

            errors.rejectValue("startDate","startDate.required");
        }

        if(officer.getEndDate() == null){

            errors.rejectValue("endDate","endDate.required");
        }

        logger.info("The Gender ID is " + officer.getGenderId().toString());

        if(officer.getPhoneNo() == null){

            errors.rejectValue("phoneNo", "phoneNo.required");
        }

    }



    /**
     * @return the validateUserNameManager
     */
    public ValidateUserNameManager getValidateUserNameManager() {
        return validateUserNameManager;
    }


    /**
     * @param validateUserNameManager the validateUserNameManager to set
     */
    public void setValidateUserNameManager(
            ValidateUserNameManager validateUserNameManager) {
        this.validateUserNameManager = validateUserNameManager;
    }



}

使用 Logger.Error("Message", e) 更新错误日志:

39024 [http-8084-2] INFO  com.crimetrack.service.OfficerRegistrationValidation  - UserName is not null so going to check if its valid for :adminz
39025 [http-8084-2] INFO  com.crimetrack.service.OfficerRegistrationValidation  - User Name in try.....catch block is adminz
39025 [http-8084-2] ERROR com.crimetrack.service.OfficerRegistrationValidation  - Message
java.lang.NullPointerException
    at com.crimetrack.service.OfficerRegistrationValidation.validate(OfficerRegistrationValidation.java:47)
    at org.springframework.validation.DataBinder.validate(DataBinder.java:725)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:815)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:367)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Unknown Source)
39025 [http-8084-2] INFO  com.crimetrack.service.OfficerRegistrationValidation  - Error Occured When validating UserName

更新

ApplicationContext.xml

<beans>
<!-- __________________________________________________________________________________________________ --> 

    <bean id="officerRegistrationValidation" class="com.crimetrack.service.OfficerRegistrationValidation">
            <property name="validateUserNameManager" ref="validateUserNameManager"/>
    </bean>

    <bean id="validateUserNameManager" class="com.crimetrack.service.ValidateUserNameManager">
            <property name="officerDao" ref="officerDao"/>
    </bean>


    <bean id="officerDao" class="com.crimetrack.jdbc.JdbcOfficersDAO" >
            <property name="dataSource" ref="dataSource" />
    </bean>

<!-- __________________________________________________________________________________________________ --> 


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${jdbc.driverClassName}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
    </bean>
<!-- __________________________________________________________________________________________________ -->    

    <bean id="propertyConfigurer" 
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>
<!-- __________________________________________________________________________________________________ -->    

    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>





  </beans>

Servlet.xml

<beans>
<!-- __________________________________________________________________________________________________ --> 

     <bean name="/hello.htm" class="com.crimetrack.web.CountryListController">
        <property name="countryManager" ref="countryManager"/>
     </bean>

    <bean name="/login.htm" class="com.crimetrack.web.AuthenticationController">
        <property name="authenticationManager" ref="authenticationManager"/>  
    </bean>

    <bean name="/officer_registration.htm" class="com.crimetrack.web.OfficerRegistrationController">
        <property name="divisionManager" ref="divisionManager" />
        <property name="positionManager" ref="positionManager" />
        <property name="genderManager" ref="genderManager"/>
    </bean>

<!-- __________________________________________________________________________________________________ -->    

    <bean name="/validateUserName.htm" class="com.crimetrack.web.OfficerRegistrationController">

        <property name="validateUserNameManager" ref="validateUserNameManager"/>    

    </bean>




<!-- __________________________________________________________________________________________________ -->    

      <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>        
      </bean>



</beans>

【问题讨论】:

  • 代码和/或堆栈跟踪会有所帮助...
  • 您应该检查抛出 NullPointerException 的位置。这就是 spring 无法注入你的依赖的地方。
  • 您能否测试一下如果您暂时禁用 Web 服务并仅发布帖子会发生什么情况?从日志来看,用户似乎第一次不存在,也许您正在那里进行某种清理?
  • 当您在com.crimetrack.service.ValidateUserNameManager 中记录最后一行时,您会丢弃有关异常的所有有用消息(堆栈跟踪)。尝试使用logger.error("Message", ex)
  • 每当发生异常并可能导致错误时,使用错误方法记录它并将异常传递给记录堆栈跟踪。如果您不打算处理错误而只是提供信息,请使用 info 方法。

标签: java forms post spring-mvc nullpointerexception


【解决方案1】:

我认为您忘记在 ValidateUserNameManager.java 中自动装配 officerDao 字段

尝试添加@Autowire

@Autowire
private OfficersDAO officerDao;

更新:

在您更新堆栈跟踪后,我认为是OfficerRegistrationValidation.java 中的validateUserNameManager 字段未自动装配。但是,这取决于 OfficeRegistrationValidation.java 中第 47 行的内容

【讨论】:

  • 我没有在任何地方使用我的代码中的@Autowire 注释,因为我觉得它很混乱,你能告诉我 xml / old 方法吗?
  • 对不起,我不知道xml配置。我发现注释很容易理解,是配置类的最佳方式。
  • 我在 OfficerRegistrationValidation 中创建了 validateUserNameManager setter 和 getter
  • 这并不意味着spring会自动注入依赖,是吗?您是否将 xml 配置为显式注入?
  • 是的,一旦你创建了 setter 和 getter,它假设执行注入,我现在正在查看 servlet 文件
【解决方案2】:

OfficerRegistrationValidation 类在每次调用时都会被实例化,如果这个类应该应用工厂 bean 来处理调用:

public final class BeanFactory() {

    private static ClassPathXmlApplicationContext context;

    private static ClassPathXmlApplicationContext getContext() {
        if (context== null) {
            context = new ClassPathXmlApplicationContext("applicationContext.xml");
        }
        return context;
    }

    public static OfficerRegistrationValidation getOfficerRegistrationValidation() {
        return (OfficerRegistrationValidation) getContext().getBean("officerRegistrationValidation");
    }
}

在控制器中进行如下调用:`BeanFactory.getOfficerRegistrationValidation().validate(....)

【讨论】:

  • 这不是一个解决方案,因为您正在为每次调用 getOfficerRegistrationValidation 创建新的 bean。这包括重新创建非常昂贵的数据库对象,并且如果某个对象应该只创建一次(单例),则可能会产生错误。你应该找到一种方法让OfficerRegistrationValidation 可重用和线程安全,这样你就可以只拥有其中一个,然后只使用 IoC 将它注入到任何你想要的地方。
  • @gigadot 什么应该是最好的方法,这意味着使用单例方法进行实例化?
猜你喜欢
  • 2016-06-29
  • 2020-06-14
  • 2021-06-03
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 2011-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多