补充知识
在动态网页工程中使用Spring,需要在web.xml
中配置一个监听器:
<!-- Spring的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
前面学习Spring都没有在Dynamic Web Project中,beans的xml文件可以放在随便什么文件下,反正可以有相应的类可以去按照路径访问它,以获得ApplicationContext上下文。
在动态网页中,标准的方式是将这个Spring配置文件起名为:
applicationContext.xml
并和web.xml
放在相同的路径下,即在WebContent/WEB-INF/
路径下。否则,需要在监听器后面加上:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
以WebContent为根的路径名/Spring配置文件名.xml
</param-value>
</context-param>
以显式指明其文件位置。
Spring整合Struts2
简述
因为Action的实例是在Struts2框架获得请求时,由Struts2创建的(这样算IoC了),不是由用户手动创建的,所以不能像配置一般的对象那样,用<bean ...>
的方式配置给Spring,需要用Struts2提供的插件来完成。
按照书上说的,这个插件就是:
struts2-spring-plugin-版本.jar
它在底层实现了ObjectFactory接口,以允许在外部完成Action实例的创建。
将这个插件加入路径中,并在struts.xml
或者struts.properties
下配置将Struts2的类生成交给Spring完成:
struts.objectFactory=spring
为Spring整合Struts2的一大好处在于,能将Action和Struts2完全解耦,在struts.xml
中配置的Action的class
属性不再是Action的实现类,而是交给Spring创建对象时,applicationContext.xml
配置文件中相应的<bean ...>
元素的id
属性。
web.xml
动态网站工程的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>Struts2_Spring</display-name>
<!-- sturts2核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<!-- 初始页面 -->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
applicationContext.xml
Spring配置bean的文件。注意控制器bean的id。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 这是一个业务逻辑类的对象,反正逻辑都是一样的,可以用[单例模式] -->
<bean id="dlLgn" class="myDeal.DealLogin" />
<!-- 这本是Struts2负责创建的Action,现在由Spring来创建,需指明是[原型模式] -->
<bean id="golog" class="myAction.LoginAction" scope="prototype">
<!-- 使用[设置注入]将业务逻辑类的对象注入给这个Action -->
<property name="dl" ref="dlLgn"></property>
</bean>
</beans>
DealLogin.java
处理业务逻辑。
package myDeal;
//对登录的处理
public class DealLogin {
public boolean login(String u, String p) {
return "lzh".equals(u) && "sb".equals(p);
}
}
LoginAction.java
控制器,组合了处理业务逻辑的类的对象。控制器对象原来由Struts2框架生成,现在与其解耦交给Spring框架生成。
package myAction;
import myDeal.DealLogin;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class LoginAction extends ActionSupport {
// 这两个信息通过Struts2框架属性注入
private String usrname;
private String password;
// 这个信息由用户的输入来根据业务逻辑生成
private String message;
// 组合一个处理用户登录的业务逻辑类的对象,该对象将由Spring单例模式注入
private DealLogin dl;
// 总是返回INDEX视图
private static final String INDEX = "index";
@Override
public String execute() throws Exception {
if (true == dl.login(usrname, password))
message = "欢迎你" + usrname;
else
message = "用户名或密码错误";
return INDEX;
}
public String getUsrname() {
return usrname;
}
public void setUsrname(String usrname) {
this.usrname = usrname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public DealLogin getDl() {
return dl;
}
public void setDl(DealLogin dl) {
this.dl = dl;
}
public static String getIndex() {
return INDEX;
}
}
struts.xml
注意现在action元素的class属性,和前面控制器bean的id相同,而不再是实现类。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 默认包,/命名空间 -->
<package name="default" extends="struts-default" namespace="/">
<!-- 这里的class需要去写Spring所配置的bean的id,而不是实现类 -->
<action name="login" class="golog">
<result name="index">/index.jsp</result>
</action>
</package>
</struts>
struts.properties
注意最后一项配置需要开启。
#激活开发模式,提供更全面的调试功能
struts.devMode=true
#开启DMI动态方法调用
struts.enable.DynamicMethodInvocation=true
#激活重新载入国际化文件的功能
struts.i18n.reload=true
struts.ui.theme=simple
struts.locale=zh_CN
struts.i18n.encoding=utf-8
struts.serve.static.browserCache=false
struts.url.includeParams=none
#指定上传文件的临时存放位置,提前建立该目录
struts.multipart.saveDir=E:/mytemp
struts.url.includeParams=none
#激活重新载入xml配置文件的功能
struts.configuration.xml.reload=true
#配置服务器的端口
struts2.url.http.port=8080
#把Struts2的类生成交给Spring完成
struts.objectFactory=spring
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录</title>
</head>
<body>
<h1>Struts2和Spring的集成</h1>
<s:form action="/login" method="post">
用户名:<s:textfield name="usrname"/>
<br>
密码:<s:password name="password"/>
<br>
<s:submit value="登录"/>
</s:form>
</body>
</html>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>正确或错误页面</title>
</head>
<body>
${message}
</body>
</html>
运行结果