SSH = Spring + Struts2 + Hibernate
Spring容器用于管理对象之间的之间的耦合度,其核心是IoC和AOP
Struts2使用了MVC模式,基于webwork的一个全新的框架
使用Struts2需要配置org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
根据使用的Struts2版本来选择响应的struts-x.x.dtd(我使用了struts-2.5.dtd),用来规定xml中的根元素与子元素之间的嵌套关系,其中根元素的名字是在这个文件中规定的
复制到xml配置文件中:
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
Spring MVC和Struts2的视图和模型的交互机制不同:
复习一下Spring MVC:
- 客户端提交请求给web服务器,web服务器解析http请求并找到匹配的DispatcherServlet的请求映射路径,把请求转交给DispatcherServlet
- 根据请求的信息通过HandlerMapping找到对应的Hander,并把处理权交给handler,再由具体的AdapterHandler对handler进行具体的调用
- Handler处理结束后将会返回一个ModelAndView给DispatcherServlet,再通过约定好的ViewResolver将逻辑视图转化为View
- 通过对ModelAndView中的model对参数进行解析最终展现出完整的view给客户端
Struts2的工作流程:
- 客户端指向一个web容器,通过调用FilterDispatcher访问ActionMapper来决定请求调用哪个Action
- 确定了Action后,FilterDispatcher将处理权交个ActionProxy
- ActionProxy通过Configuration Manager来找到需要调用的Action类
- ActionProxy创建一个ActionInvocation的实例来调用Action,并根据返回的String结果来选择返回的类型及页面
- 将最终结果返回客户端
public class DemoAction {
public String execute(){
System.out.println("Hello world");
//返回的值 success代表jsp的名称
return "success";
}
<struts>
//目录名 类似于父类
<package name="demo" namespace="/demo" extends="struts-default">
<action name="hello" class="ssh.day01.DemoAction" method="execute">
<result name="success">
/WEB-INF/ok.jsp
</result>
</action>
</package>
</struts>
在表单提交时,input中的name值对应为JavaBean中的属性值。
使用SSH实现下载:
图片:
<action name="image" class="ssh.day01.ImageAction" method="execute">
<result name="success" type="stream">
<param name="contentType">
image/png
</param>
<!-- inputStream的名字 -->
<param name="inputName">
img
</param>
<!-- 下载 -->
<param name="contentDisposition">
attachment;filename="img.png"
</param>
</result>
</action>
excel表格:
<action name="excel" class="ssh.day01.ExcelAction" method="execute">
<result name="success" type="stream">
<param name="inputName">
excel
</param>
<param name="contentType">
application/vnd.ms-excel
</param>
<param name="contentDisposition">
attachment;filename="1.xls"
</param>
</result>
</action>
通过导入json-plugin来将控制器全部的bean属性序列化为json对象属性返回浏览器:
<action name="jr" class="ssh.day01.JsonResultAction" method="execute">
<result name="success" type="json">
<!-- 只选中一个属性 -->
<param name="root">
jsonResult
</param>
</result>
</action
Struts2的一大优点是可以解除与web容器的耦合性,即可以脱离web容器单独使用,在底层struts2容器会将session,request,application中的信息同步到HttpXXXXX中
有两种方式获得:
ActionContext ctx = ActionContext.getContext();
Map<String,Object> session = ctx.getSession();
或者实现SessionAware,并实现其setSession方法
public abstract class AbstractAction extends ActionSupport implements SessionAware,ApplicationAware,RequestAware {
protected Map<String,Object> session;
protected Map<String,Object> application;
protected Map<String,Object> request;
public void setSession(Map<String, Object> session) {
this.session=session;
}
public void setRequest(Map<String, Object> request) {
this.request=request;
}
public void setApplication(Map<String, Object> application) {
this.application=application;
}
}
这个类继承的ActionSupport是Struts2提供的基础类,用于复用公共代码
如何整合Spring:
使用struts2-spring-plugin,使用Spring和Struts2整合,可以利用Spring管理Action对象,可以作为控制器注入业务层
需要使用listener触发spring容器
org.springframework.web.context.ContextLoaderListener
在Spring mvc中多个请求复用一个对象(单例), 在struts2在线程安全的基础上建议多个请求多个对象(原型)
服务器Tomcat:
线程池-->线程-->调用主控制器-->Filter-->Action-->XXXservice
当多个线程同时并发访问一个临界资源的时候,就有线程安全性问题
所以每创建一个action对象,使用spring管理对象是,使用原型模式
valueStack 值栈:
每次访问action都会创建action对象,每个action对象里都有一个值栈对象
值栈分为两个部分,root和context
一般我们传值操作的是root中的内容
context中则是像request session application等
可以通过OGNL表达式的<s:debug/>查看