起源
随着Internet技术的广泛使用,Web技术已经广泛应用于Internet上,早期的Web应用全部是静态的HTML页面,用于将一些文本信息呈现个浏览者,但这些信息固定写在HTML页面,不具备与用户交互的能力,没有动态显示的功能。 ——静态页面
很自然,人们希望Web应用里应该包含一些能动态执行的页面,Servlet由此产生。Servlet是基于Java语言创建,而Java语言内建了多线程支持,进而大大提高了动态Web应用的性能。
——动态页面(Servlet)
随着实际Web应用使用越来越广泛,Web应用的规模也越来越大,动态Web应用的维护成本越来越大,即使只需要修改页面的一个简单按钮,必须打开繁杂的动态脚本的页面源文件进行修改(存在风险,可能引入错误)。为了提升Web应用程序的可维护性和重复使用性,Java开发人员提供了一些教佳的开发模式。常见的两种JSP应用架构为Model1与Model2.
在Model1模式下,整个Web应用几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接做出响应。用少量的JavaBean来处理数据库连接、数据库访问等操作。但它的局限性非常明显:JSP页面身兼View和Controller两种角色,将控制逻辑和表现逻辑混杂在一起,从而导致代码的重用性非常低,增加了应用的扩展性和维护的难度。
Model2已经是基于MVC架构的设计模式。在Model2架构中,Servlet作为前端控制器,负责接收客户端发送的请求,在Servlet中只包含控制逻辑和简单的前端处理;然后,调用后端JavaBean来完成实际的逻辑处理;最后,转发到相应的JSP页面处理显示逻辑。
相比: Model1的实现比较简单,适用于快速开发小规模项目。由于引入了MVC模式,使Model 2具有组件化的特点,更适用于大规模应用的开发。
——Model1与Model2
Struts是Apache软件基金组织Jakarta项目的一个子项目,是世界上第一个发布的MVC架构,其前身是JSPModel2架构。它以一种更加优雅的方式来实现控制器,并提供如国际化,类型转换等一系列的功能。是MVC设计模式中的一个经典产品,它为Servlet/JSP技术的应用提供技术框架。
——Struts(MVC架构)
架构
Struts作为MVC模式的典型实现,对Model、View和Controller都提供了对应的实现组件,如下图
1、Model
Model部分由ActionForm和JavaBean组成:
ActionForm用于封装用户请求参数(自动封装到ActionForm对象中),该对象被ActionServlet转发给Action,然后Action根据ActionForm里的请求参数处理用户请求。
JavaBean封装了底层的业务逻辑,包含数据库访问等。复杂应用中,JavaBean可能是EJB组件或其他的业务逻辑组件。
2、View
Struts的View采用JSP实现。Struts提供了丰富的标签库,通过这些标签库可以最大限度地减少脚本的使用。这些自定义的标签库可以实现与Model的有效交互,并增加了显示功能。
3、Controller
由两部分组成:系统核心控制器和业务逻辑控制器
系统核心控制器对应ActionServlet,该控制器由Struts框架提供,继承HttpServlet类,可配置成一个标准的Servlet。该控制器负责拦截所有的Http请求,然后根据用户请求决定是否需要调用业务逻辑控制器,如果需要调用,则将请求转发个Action处理,否则直接转向请求的JSP页面。
业务逻辑控制器负责处理用户请求,但业务逻辑控制器本身并不具有处理能力,而是调用Model来完成。
调用流程
1、客户端浏览器发出请求。
2、服务器端的struts中心类Actonservlet找到struts-config.xml文件,并放入内存,将文件中的内容作为请求路径映射。
3、ActionServlet类在struts-config.xml文件中找到相关的请求路径映射后填充ActonForm类,将前台传进来的表单域打包成Bean。
4、转到Action类进行业务逻辑功能的实现,比如增、删、改、查数据库中的数据。
5、通过struts-config.xml文件的映射,找到逻辑处理结束后显示给客户端用户看到的页面,转发功能的实现是通过Actionforward对象。
1、首先在web.xml添加相应的struts配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<!-- 默认一致就可以删掉 -->
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<!-- 日志级别解析,可不要 -->
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<!-- 大于等于0,tomact已启动将servlet new了,调用初始化方法 -->
<!-- 建议配置为大于等于0 -->
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2、然后在config所对应的目录下添加struts配置文件struts-config.xml
注:一个Action只能对应一个ActionForm;而一个Form可以被多个Action调用
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<!-- ActionServlet一初始化将其读到内存里 -->
<struts-config>
<!-- ActionForm -->
<form-beans>
<!-- name:名称 type:类路径 -->
<form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"/>
</form-beans>
<!-- 注册Action -->
<action-mappings>
<!-- name:名称 type:类路径 path:客户端(JSP)提交到服务器端时指定的路径(Form表单中的action=”/login.do" -->
<action path="/login"
type="com.bjpowernode.struts.LoginAction"
name="loginForm"
scope="request"
>
<forward name="success" path="/login_success.jsp" />
<forward name="error" path="/login_error.jsp"/>
</action>
</action-mappings>
</struts-config>
3、ActionForm
public class LoginActionForm extends ActionForm {
// username与jsp界面上的username无关
private String username;
private String password;
public String getUsername() {
return username;
}
// set后面的Username与界面上的username一致
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4、Action
public class LoginAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 界面获得数据放在定义好的ActionForm
LoginActionForm laf = (LoginActionForm) form;
// ActionForm封装好的直接用就可以,也可以使用getParmeter
String username = laf.getUsername();
String password = laf.getPassword();
if ("admin".equals(username) && "admin".equals(password)) {
// 登录成功
return mapping.findForward("success");
} else {
// 登录失败
return mapping.findForward("error");
}
}
}
登录页面
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!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=GB18030">
</head>
<body>
<%--必须使用.do,才可以--%>
<form action="login.do" method="post">
用户:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
成功页面
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!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=GB18030">
</head>
<body>
${username},登录成功
</body>
</html>
失败页面
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!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=GB18030">
</head>
<body>
${username},登录失败
</body>
</html>
当用户名和密码都输入为admin时,登录成功
核心对象
a) Actionservlet是核心控制,URL 地址映射、ActionForm的匹配、 Action 的执行都需要这个类来进行导航
b) Actionmapping:它们可将请求URI映射到Action类,并且将Action类与ActionFormbean相关联
c) Actionform:收集表单数据
d) Action:完成所需的业务逻辑,确定要跳转的页面
e)Actionforward:用来封装转发路径的
优缺点
优点
实现MVC模式,机构清晰,使开发者只关注业务逻辑的实现
丰富的标签库,大大提高开发效率
页面导航:通过一个配置文件把握整个系统间的联系
缺点
支持的表现曾技术单一(只支持JSP)
与Servlet API严重耦合,难于测试
对Servlet依赖性过强,Struts处理时必须依赖ServletRequest和ServletResponse,无法摆脱Servlet容器。
小结
使用Struts框架可以提高系统的可维护性和可重用性,但同时也存在很多问题。struts宏观介绍先总结到这里,项目使用过程中再去深入学习。