一、有问题的applicationContext.xml文件内容如下:<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="省略头部"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
......省略    
         </bean>   
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
省略
<property name="mappingResources">
<list>
<value>com/account/model/Account.hbm.xml</value>                             <value>com/account/model/User.hbm.xml</value>
</list>
</property>
</bean>

<!-- 用户模块bean -->
<bean id="userDao"
class="com.account.dao.hibernate.UserDaoHibernate" abstract="false"
p:sessionFactory-ref="sessionFactory">
</bean>
<bean id="userManager"
class="com.account.service.impl.UserManagerImpl" abstract="false"
p:userDao-ref="userDao">
</bean>
<bean id="user" class="com.account.action.UserAction" scope="prototype"
p:userManager-ref="userManager">
</bean>

<!-- 账户模块bean -->
<bean id="accountDao"
class="com.account.dao.hibernate.AccountDaoHibernate" abstract="false"
p:sessionFactory-ref="sessionFactory">
</bean>
<bean id="accountManager"
class="com.account.service.impl.AccountManagerImpl" abstract="false"
p:accountDao-ref="accountDao">
</bean>
<bean id="account" class="com.account.action.AccountAction" scope="prototype"
p:accountManager-ref="accountManager">
</bean> <!--   配置事务管理器 -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置哪些方法需要进行事务管理 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
省略
</tx:advice>
<!-- 配置哪些类需要进行事务管理 -->
<aop:config>
省略
</aop:config>  
</beans>
二、问题描述:
1、项目是一个ssh项目,配置文件中涉及2个模块:user和account。user模块现在可以正常CRUD。
2、account模块pojo类:
public class Account{
private String name; public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
}
}
3、account模块action:
public class AccountAction extends ActionSupport {
private Account account;
private AccountManager accountManager;
//省略get、set方法
}
    //测试方法
    public String saveOrUpdate(){
try{
         System.out.println("/user/account!saveOrUpdate is invoked:"+account.getName());
        }catch(Exception e){
e.printStackTrace();
}
return SUCCESS;
    }
}
4、页面表单
<input type="text" name="account.name" ></input><br>,提交给 AccountAction 的saveOrUpdate()方法;
5、问题:当我把applicationContext.xml当中标红的user模块部分配置删除后, AccountAction 的saveOrUpdate()方法中account.getName()可以正常取得name属性值,如果保留user模块部分配置,则无法将参数传递给pojo类account,报如下空指针异常:
java.lang.NullPointerException
at com.account.action.AccountAction.saveOrUpdate(AccountAction.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:440)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:279)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:163)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:249)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:122)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:148)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:93)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:235)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:89)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:128)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:104)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:126)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:138)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:148)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:128)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:468)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
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:128)
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:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:662)

解决方案 »

  1.   

    AccountAction.java:35行是什么?
    空指针,猜测应该是一些bean没有注入。
      

  2.   

    35行就是:System.out.println("/user/account!saveOrUpdate is invoked:"+account.getName());
    但是我删除了红色部分的bean配置就正常了,这么看来,还多配置bean了。但是不能删啊,要用user模块的
     
      

  3.   


    account.getName()的account為空,你看看,account如何傳入的。
      

  4.   

    4、页面表单
    <input type="text" name="account.name" ></input><br>,提交给 AccountAction 的saveOrUpdate()方法;
    --用表单提交传参数(DomainModle方式)
      

  5.   


    你封裝的account為null,AccountAction.java你是如何幫頂account的?
      

  6.   

    3、account模块action:
    public class AccountAction extends ActionSupport {
     private Account account;
     private AccountManager accountManager;
     //省略get、set方法
    }
    ---有struts通过DomainModle方式,调用AccountAction 的setAccount()方法,就可以讲表单参数传进去了。
      

  7.   


    你debug看看,調用saveOrUpdate方法之前,account是null嗎?
      

  8.   

    struts2会帮我们new一个account出来的,还有哪里有疑问啊?
      

  9.   


    從你的報錯可以看出,account為null
      

  10.   


    你把AccountAction全貼出來。
      

  11.   

    package com.account.action;import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;import com.account.model.Account;
    import com.account.model.User;
    import com.account.service.AccountManager;
    import com.googlecode.jsonplugin.annotations.JSON;
    import com.opensymphony.xwork2.ActionSupport;public class AccountAction extends ActionSupport {
    private static final long serialVersionUID = -3776314198730199653L;
    private AccountManager accountManager;
    private Account account;
    private Integer id;
    private Integer accountTypeId;
        private String result;// ajax返回结果 public void setAccountManager(AccountManager accountManager) {
    this.accountManager = accountManager;
    } public void setId(Integer id) {
    this.id = id;
    }
        @JSON(serialize = false)
    public Integer getId() {
    return id;
    }    @JSON(serialize = false)
        public Account getAccount() {
    return account;
    } public void setAccount(Account account) {
    this.account = account;
    } @JSON(serialize = false)
    public Integer getAccountTypeId() {
    return accountTypeId;
    } public void setAccountTypeId(Integer accountTypeId) {
    this.accountTypeId = accountTypeId;
    }
        @JSON(serialize = true)
    public String getResult() {
    return result;
    }
        //账户添加&修改
        public String saveOrUpdate(){
    System.out.println("-------------");
    try{
    System.out.println("/user/account!saveOrUpdate is invoked:"+account.getName());
            this.result = "";
            //从session中取得当前用户对象
            HttpSession session=ServletActionContext.getRequest().getSession();
            User user = (User)session.getAttribute("user");
    }catch(Exception e){
    e.printStackTrace();
    }
            //判断当前用户,该账户类型下是否已经存在要添加的账户名称
    /*if(accountManager.get(user,account.getAccountType(),account.getName()).size()==0){
    accountManager.saveOrUpdate(account);
            this.result = SUCCESS;
    }else{
            this.result = ERROR;
    }*/
            //this.result=accountManager.saveOrUpdate(accountTypeId,account);
    return SUCCESS;
        }}
      

  12.   

    1、你這個是ajax請求的嗎?
    2、如果不是ajax請求,那就真奇怪了。
      

  13.   

    是ajax请求,那是什么原因呀?
    function submit_account(form_id,win_id){
    //使用easyui-validatebox方式验证表单
    /*var validate_result=$("#"+form_id).form('validate');
    if(validate_result==false){
    return validate_result;
    }*/
    var form_serialize=$("#"+form_id).serialize();
    alert(form_serialize);
        $.post("user/account!saveOrUpdate", $("#"+form_id).serialize(), function(data){
            if(data.result=="success"){
             $('#'+win_id).window('close');//关闭密码修改window
             $.messager.alert('系统提示','密码修改成功!');
            }else if(data.result=="error"){
             $.messager.alert('系统提示','旧密码不正确,密码修改失败!');
            }else{
             $.messager.alert('系统提示','未知错误!');
            }
        }, 'json');
    }
      

  14.   


    你这样,debug,看看。
    jquery请求的时候,异步请求,你没有提交表单,account的值会自动赋值吗?
      

  15.   

    我把红色的user配置部分删除掉就可以出结果,说明是会自动赋值的。
    这是执行结果:
    /user/account!saveOrUpdate is invoked:qqqqq
      

  16.   

    奇怪了,但是你并没有在AccountAction 中使用红色的部分呀。
    你也没有用accountManager。
      

  17.   

    我试着把:
    <bean id="user" class="com.account.action.UserAction" scope="prototype"
     p:userManager-ref="userManager">
     </bean> 
    中的id改为【userAction】把
     <bean id="account" class="com.account.action.AccountAction" scope="prototype"
     p:accountManager-ref="accountManager">
     </bean>
    中的id改为【accountAction】
    然后在struts.xml中,class的名字相应的做修改:
    <action name="user" class="userAction">
    <result type="json" />
    </action>

    <action name="account" class="accountAction">
    <result type="json" />
    </action>
    就ok了。
    纯粹是瞎试出来的,都不知道什么原因了?大家帮忙看看哇,谢谢!
      

  18.   

    应该是struts 2的处理机制。
    要求,<action name="user" class="userAction">name和class名字不可以一样的缘故。