项目使用了SSH,用注解的方式装备bean,如果只在Dao,service层注解。没有问题可以正常启动tomcat,bean也装配成功,可以正常访问。如果action也加了注解就会启动失败,并且报错
启动tomcat时的异常:
[ERROR] 2016-02-25 17:21:24,427 [ pool-2-thread-1:1123 ] method:initWebApplicationContextContext initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'policeLoginAction' defined in file [E:\Workspaces\eclispe\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\zyhCity160129\WEB-INF\classes\com\safe\action\police\PoliceLoginAction.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.safe.action.police.PoliceLoginAction]: Constructor threw exception; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1076) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1021) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4765) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5260) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1525) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1515) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.safe.action.police.PoliceLoginAction]: Constructor threw exception; nested exception is java.lang.NullPointerException at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:164) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1069) ... 22 more Caused by: java.lang.NullPointerException at org.apache.struts2.ServletActionContext.getRequest(ServletActionContext.java:112) at com.safe.action.BaseAction.<init>(BaseAction.java:23) at com.safe.action.police.PoliceLoginAction.<init>(PoliceLoginAction.java:15) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148) ... 24 more
 
 
 
 
package com.safe.action.police;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.safe.action.BaseAction;
import com.safe.model.Police;
import com.safe.service.PoliceService;
import com.safe.util.ConstantUtil;
@Controller
public class PoliceLoginAction extends BaseAction {
	private static final long serialVersionUID = 1L;
	@Autowired
	private PoliceService policeService;
	private String policeNo;
	private String pwd;// 叫做授权码 只有在开发测试时使用 2016年1月20日15:34:02
	private String token;
	public String getPoliceNo() {
		return policeNo;
	}
	public void setPoliceNo(String policeNo) {
		this.policeNo = policeNo;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getToken() {
		return token;
	}
	public void setToken(String token) {
		this.token = token;
	}
	@Override
	public String execute() throws Exception {
		String returnStr = SUCCESS;
		System.out.println(
				new SimpleDateFormat("yyyy-MM-dd HH🇲🇲ss").format(new Date()) + " login:" + policeNo + "---" + pwd);
		Police police = policeService.login(policeNo, pwd, token);
		if (police == null) {
			message = "登录失败!";
			code = 0;
			returnStr = "fail";
			// return "fail"; 返回json的时候,如果此处return,就不会执行后面的发送json
		} else {
			jsonMap.put("token", police.getToken());
			jsonMap.put("police", police);
			session.setMaxInactiveInterval(ConstantUtil.HTTPSESSION_life);// 设置session闲置间隔(有效期),单位:秒
			// 登陆状态标识符
			session.setAttribute("policeId", police.getId());// 登录警员的Id
			session.setAttribute("loginName", policeNo);// 验证在线状态时使用,如果为null则表示没有登录
			session.setAttribute("identity", "police");// 登陆者身份类别
		}
		returnJson();
		return returnStr;
	}
} 
 
 
 
 
package com.safe.action;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.safe.util.ConstantUtil;
import com.safe.util.JsonUtil;
public class BaseAction extends ActionSupport {
	private static final long serialVersionUID = 1L;
	
	protected int code = 1;// 响应登陆状态码,1成功 0失败
	protected String message = ConstantUtil.RETURN_OK;
	
	protected Map<String, Object> jsonMap = new HashMap<String, Object>();	
	protected HttpSession session = ServletActionContext.getRequest()//这一行报空指针
			.getSession(); 
如果,没有在action加@Controller注解,则没有异常,并且BaseAction中的函数可也以正常调用。
另外一个问题,spring配置action时该使用单例还是其他的作用域?版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
最优的解决方案就是不用struts2了,改用springmvc,我保证,你用了之后就会再也不想用回来struts2的真的吗?谢谢。要获取session不应该使用这种方式,在省城bean的时候这个方法返回的还是空指针,要获取session应该是实现相应的接口,完成依赖注入回复<aclass='referer'target='_blank'>@颖辉小居:没毛病啊,不就是存值取值嘛,这里面的值和httpsession的值是对应的。@controller注解原先是给springmvc使用的,默认是单例,但是struts2用的时候不要单例,每次请求新建回复<aclass='referer'target='_blank'>@阿信sxq:这个拿到的是map不是HttpSession@OverridepublicvoidsetSession(Map<String,Object>session){this.session=session;}回复<aclass='referer'target='_blank'>@阿信sxq:谢谢,还有一个问题:spring配置action时该使用单例还是其他的作用域?回复<aclass='referer'target='_blank'>@颖辉小居:实现“org.apache.struts2.interceptor.SessionAware“即可可以说的详细点吗?自己顶 异常原因分析:因为action加了注解,而容器使用的是ApplicationContext(默认启动容器立即加载Bean)。在action中使用了父类BaseAction的属性session,所以启动Spring容器时就会调用session的初始化方法ServletActionContext.getRequest()
.getSession();此时,没有用户访问,也就没有请求,所以request为空,调用.getSession()方法时报空指针。
新的疑问:spring容器applicationContext默认创建Bean是单例作用域。Struts2的action是多例的,如果给action加上注解被Spring管理。会不会在作用域上又冲突?第三种办法:不在action上加Spring注解(即不被Spring管理)。Struts2会自动为每一次请求创建一个action实例(线程安全),未发现什么问题。第二种办法IOC注入:BaseAction实现接口ServletRequestAware并实现方法setServletRequest。可以注入HttpRequest实例,通过request.getSession()获得HttpSession找到一个解决办法给ACTION加注解@Lazy(true),但是感觉这个不是最好的办法。想不到还有人在使用struts。。。。。