为什么会选择struts
model2的缺点
- 流程凌乱:Servlet完成对用户请求的处理后,下一个页面是什么?如何跳转?都是在servlet里面用代码实现的,导致servlet既要处理请求,又要负责页面的流程,功能不单一,而且最重要的是,很难把握整个系统的页面流程,因为流程被分散到各个servlet里面了。
- 数据传递无序:Model2里面,通常情况下,数据都是用javaBean传递,使用比较麻烦,而且面临复杂数据嵌套使用JavaBean会力不从心。
- 缺乏辅助功能:几乎所有东西又要从头做起,没有统一的分发调度、验证框架、国际化、本地化、例外消息处理等。
struts解决了这些问题,但是也有缺点,自己百度缺点吧。。。
然后在1的接触上,改进了很多,出现了Struts2,Tapestry,SpringMVC等。
struts2的组成
介绍了一下struts2的组成:
webwork和struts合并后,根据功能的细分和设计,拆分出一个叫xwork部分,用来处理与wen无关的部分,也就是与servlet无关的部分,比如用户数据的类型转换、动作调用之前的数据验证、动作的调用等。
所以struts2可以看成由web相关的struts2部分+与web无关的xwork部分组成。
优点是:
1. 通过简单、集中的配置来调度动作类
2. 提供简单统一的表达式语言来访问所有可供访问的数据
3. 提供内存式的数据中心,所有可访问的数据都在内存中
4. 提供在动作类执行的前或后附加执行一定功能的能力,实现AOP面向切面编程
5. 提供标准的强大的验证框架和国家化框架。
框架图如下:
先了解一下名词概念,前端控制器FilterDispatcher、动作action、结果result等。
(1)FilterDispatcher: 用户请求首先到达FilterDispatcher,负责根据用户提供的URL和struts.xml中的配置,选择合适的action,让这个action处理用户请求。它其实是一个过滤器。
(2) Action: 在用户请求经过FilterDispatcher之后,被分发到了合适的action对象。action负责把用户请求中的参数组装成合适的数据模型,并调用相应的业务逻辑进行很正的功能处理,然后获取下一个视图展示所需要的数据。
Action能实现与servletAPI的解耦,使得Action里面不需要直接去应用和使用httpServletrequest和response等接口,因而使得action的单元测试更加简单,而且强大的类型转换也使得我们稍作了很多重复的工作。
(3)视图:用来把动作中获取到的数据展现给用户。
下面看如果用struts来开发基于MVC的web应用】
万年不变的helloworld….将要从Servlet+JSP+JavaBean实现MVC开始,再过渡到Struts2的开发。
编写JavaBean
用model2来实现MVC,模型部分是使用JavaBean来实现的,而且视图和控制器之间的数据交互也是通过JavaBean来实现的,so先来写JavaBean。
先不实现什么复杂的业务逻辑,知识一个简单的数据封装model,有3个属性,分别是account,password,submitFlag。其中的submitFlag是用来封装提交请求的标记,为它们提供相应的getter和setter方法,示例代码如下:
package cn.javass.hello.servletiml.vo;
public class HelloWorldModel {
private String account;
private String password;
private String submitFlag;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSubmitFlag() {
return submitFlag;
}
public void setSubmitFlag(String submitFlag) {
this.submitFlag = submitFlag;
}
public String toString() {
return "account=" + account + ",password=" + password + ",submitFlag=" + submitFlag;
}
/*
* 示例方法,表示可以执行业务逻辑处理的方法。
* 比如对数据进行增删改查等
* */
public void businessExecute()
{
System.out.println("正在进行业务处理=======>");
}
}
编写Servlet
Servlet在model2中相当于控制器,简单实现一下。这个servlet的工作有如下:
1. 收集Request传递过来的参数。
2. 把这些参数组织成为模型需要的类型。
3. 调用模型进行逻辑功能处理
4. 选择下一个页面,先准备好下一个页面需要的数据,然后转向下一个页面。
代码如下:
package cn.javass.hello.servletimpl.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.javass.hello.servletimpl.vo.HelloWorldModel;
/**
* Servlet implementation class HelloWorldServlet
*/
@WebServlet("/HelloWorldServlet")
public class HelloWorldServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloWorldServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.收集参数,不用做了,通过JavaBean传入。
//2.组织参数,也不用做了,已经组织好了,把数据封装成了JavaBean。
//这里只需要获取封装好的JavaBean即可。
HelloWorldModel hwm = (HelloWorldModel)request.getAttribute("HelloWorld");
//调用模型的逻辑功能处理
hwm.businessExecute();
//这里简单输出一下传入的参数
System.out.println("用户输入的参数为====>"+hwm);
//4: 根据逻辑处理的结果来选择下一个页面,这里直接选择转向欢迎界面。
//4.1: 先把需要欢迎页面显示的数据准备好。
request.setAttribute("hwm", hwm);
//4.2: 转向欢迎界面
request.getRequestDispatcher("/servletimpl/welcome.jsp").forward(request, response);
}
}
配置web.xml和JSP页面