整合SSH框架(2)
Spring4+hibernate4+Struts2的整合,整合完成后我会把这个项目上传上去,但是我的建议是最好还是自己在自己的电脑上自己整合一下,我不保证一定没问题
1、整合Struts2之前
前面我们已经整合了spring4和hibernate4,接下来我们继续整合Struts2
引入一些Struts2的包
其中有部分是重复的,比如commons-logging这个包,这个大家自己看着删
2、开始整合,我们先配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!-- 在web容器中实例化spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value><!-- 这个指定spring的配置文件,默认从web根目录寻找配置文件,我们可以通过spring提供的classpath:前缀指定从类路径下 寻找 --> </context-param> <!-- 实例化spring容器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <!-- <init-param> <param-name>config</param-name> <param-value>struts.xml</param-value> </init-param> --> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
这个Struts2的部分和单个的Struts2的配置一样,不一样的地方就是加入了用web.xml管理spring的实例化
这里我们先看看用这个org.springframework.web.context.ContextLoaderListener监控spring实例化的文件吧实例化文件放到那里去了???
我们打开这个类的源码,找到这个方法,进入到initWebApplicationContext里面去看看,
在源代码里面我们可以找到
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
这下我们知道了,他是放到了servletContext里面去了,后面我们就在这个里面取出来
3、接下来我们继续配置Struts2.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="person" extends="struts-default"> <action name="PersonAction" class="cn.cutter_point.web.action.PersonAction" method="execute"> <result name="list">page/personlist.jsp</result> </action> </package> </struts>
我们就以前面建立的person类为代表,取得所有的persons对象
我们写一下我们的action类,来处理跳转,以及调用业务
PersonAction.java
/** * 功能:集成ssh框架 * author:cutter_point * 时间:2015年3月29日17:30:07 */ package cn.cutter_point.web.action; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import cn.cutter_point.service.PersonService; import com.opensymphony.xwork2.ActionSupport; public class PersonAction extends ActionSupport { @Override public String execute() throws Exception { //获取实例,方法1 ServletContext sc = ServletActionContext.getRequest().getSession().getServletContext(); WebApplicationContext wac = (WebApplicationContext) sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); //方法2 WebApplicationContext webApplicationContext = WebApplicationContextUtils. getRequiredWebApplicationContext(ServletActionContext.getServletContext()); if(wac == webApplicationContext) { System.out.println("ok!!!"); } PersonService personService = (PersonService) wac.getBean("personServiceBean"); HttpServletRequest request = ServletActionContext.getRequest(); request.setAttribute("persons", personService.getPersons()); return "list"; } }
好的,如果你认真看了上面的代码的话,你会发现实例化spring的方法有两个,但是到底哪个好,我也不知道,反正两个取出来的东西是一模一样的,没有什么区别
Struts2获取request三种方法
struts2里面有三种方法可以获取request,最好使用ServletRequestAware接口通过IOC机制注入Request对象。
在Action中获取request方法一:
在Action中的代码:
Map request =(Map)ActionContext.getContext().get("request");
List<Task> tasks = taskManager.findAll();
request.put("tasks", tasks);
在JSP页面中获取其中的值:
<s:iterator id="task"value="#request.tasks">
<trclass="table_header">
<td><s:propertyvalue="#task.tname"/></td>
<td><s:propertyvalue="#task.tuid"/></td>
<td><s:propertyvalue="#task.tstartTime"/></td>
<td><s:propertyvalue="#task.tendTime"/></td>
<td><s:propertyvalue="#task.tstate"/></td>
<td><inputtype="radio" id="choose" name="choose"onclick="getId(this.value)" value="<s:propertyvalue=‘#task.tid‘/>"/></td>
</tr>
</s:iterator>
--------------------------------------------------------------------------------------------
方法二:通过ServletActionContext类来获取,使用struts2经验如果处理get传参是中文,只能使用该方法进行处理乱码问题
Action中代码:
HttpServletRequest request =ServletActionContext.getRequest();
request.setAttribute("username","zhangsan");
在jsp中获取其中的值
<s:propertyvalue="#request.username">或者${requestScope.req}
--------------------------------------------------------------------------------------------
方法三:通过ServletRequestAware接口通过IOC机制注入Request对象
Action中的代码:
Action实现ServletRequestAware接口,实现接口中的方法
private HttpServletRequest request;
//实现接口中的方法
public void setServletRequest(HttpServletRequestrequest){
this.request = request;
}
//然后在execute()方法中就可以使用了
public String execute(){
request.setAttribute("username", "zhangsan");
request.getSession().getServletContext().getApplication(); //得到Application
}
该方法必须要实现,而且该方法是自动被调用
这个方法在被调用的过程中,会将创建好的request对象通过参数的方式传递给你,你可以用来赋给你本类中的变量,然后request就可以使用了
注意:setServletRequest()方法一定会再execute()方法被调用前执行
4、我们接下来写一下我们的jsp文件
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>SSH之人物列表</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <s:iterator var="persons" value="#request.persons"> id号是:<s:property value="id"/> 名字是:<s:property value="name"/><br> </s:iterator> </body> </html>
这里我们来扩充一下Struts2的标签的知识
struts2标签使用中,什么时候用#,什么时候可以不用#
比如我看有些是这样写的: <s:iterator id="page" value="List"></s:iterator> <s:iterator id="page" value="#List"></s:iterator> 哪位能说的详细点,不要说在什么根不根中的,这个纠结了我好久。
值栈中的对象的不使用#,非值栈中的对象使用# 如果你不理解值栈的作用,简单点理解:当前action,或者处于action链中的action所拥有的属性,并且为该属性提供了getter和setter方法,那么在jsp中就不需要使用#,除此之外需要使用#,那么从这里你就可以知道action的属性如果提供了getter和setter方法,那么这些属性值就会放置到值栈中
struts标签<s:iterator>怎么用
把action中的List对象,在页面用<s:iterator>把List的内容循环显示出来 首先有一个User对象 public class User { private Integer userId; private String userName; private String userPwd; //get和set方法 ........... } action中的代码 List list = new ArrayList(); User user1 = new User(); user1.setUserId(1); user1.setUserName("zhangsan"); user1.setUserPwd("123456"); list.add(user1); User user2 = new User(); user2.setUserId(2); user2.setUserName("lisi"); user2.setUserPwd("1234"); list.add(user2); 在把list放在request中,好在jsp页面中能拿到 jsp页面中的代码 <table> <s:iterator value="list" id="别名">//这个id加不加都没事 <tr> <td><s:property value="user.userId"/></td>//这也可以写成<s:property value="别名.user.userId"/> <td><s:property value="user.userName"/></td> <td><s:property value="user.userPwd"/></td> </tr> </s:iterator> </table> 这样就可以了!
参考:
http://zhidao.baidu.com/question/172130287
5、启动tomcat
打开http://localhost:8080/ssh/PersonAction(我使用的是tomcat,具体tomcat怎么搞,就不在这里啰嗦了)
控制台运行结果:
项目下载地址:http://download.csdn.net/detail/cutter_point/8544889