开源MVC框架Struts (一) 对Servlet进一步封装和抽象
-
介绍
- 先不说Struts详细的工作流程以及其内部组成原理,先介绍一下它是干什么用的?什么时候用?想了解Struts前提你必须了解MVC设计模式,它是根据MVC开发出来的一套标准开发流程,你也可以把框架理解为将项目开发中的某部分操作流程提取出来,形成很多人都用的东西,既然叫做框架当然也会有框的限制,必须依据框架标准开发。
- 以前听说框架,经常联想到生活中装东西的框(苹果框)、建楼最初的钢筋骨架等,同软件里面的框架对比一下还真的很类似看来以前的理解是根据生活经验理解,这个词是从生活中得来,这也是为什么软件中把一个固定的开发流程叫做框架,很形象。
- 使用Struts的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。可以说Struts是基于MVC的产品,应在Web开发的表示层。
-
Servlet开发
- 不管你是在Model1或Model2中开发Web Project,应用层都会涉及到好多的JSP或Servlet,页面一多了之后就会觉得很乱找某一个页面需要找半天。
-
在Model2即MVC模式中虽然页面跳转的很清晰了,只可惜它违背了一个编程原则:OCP
- 在程序里面我们要尽可能的遵循OCP原则对扩展开放对修改关闭,这是各种模式的精粹和指导方针,控制页面跳转(转发或重定向)语句都写在了Servlet里面,如果要改变跳转页面就必须修改代码并从新编译才行
- JSP与Servlet交互过程中会涉及到频繁的数据类型转换,然而Java又是一个安全数据类型语言,这就导致了Jsp与Servlet通信常常会因为数据类型不一致引发错误,小错误出现大问题得不偿失。
- 除了上面提及的问题还有很多不足之处,不一一列举。
-
Struts框架好处
- Struts是对Servlet控制页面跳转、类型转换等做了进一步封装,解决了Servlet开发带来的诸多问题,有利于维护。
-
页面导航(配置文件struts-config.xml)
- 这样做,使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
-
标签库(taglib)
-
Taglib是Struts的标记库,灵活动用,能大大提高开发效率。
- 不过Taglib并不经常使用,毕竟它是Struts自己的库,在移植和通用性方面就不会很好,还需要学习一遍如何使用,推荐使用JSTL、EL库。
-
Taglib是Struts的标记库,灵活动用,能大大提高开发效率。
- 另外还有封装数据类型转换(ActionForm)、表单验证(validate)等等
- 在学习每个新东西时似乎都是拿登录做为例子,我们也用登陆来说明它们的区别。
-
登录实例对比
-
Servlet、Jsp、MVC
-
JSP页面
-
<%@ 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"> <title>Insert title here</title> </head> <body> <form action="login.do" method="post"> 用户名:<input type="text" name="username"> 密码:<input type="password" name="password"> <input type="submit" value="登录"> </form> </body> </html>
-
-
Servlet
-
package com.bjpowernode.struts; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.omg.CORBA.Request; public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //取得表单参数 String username=request.getParameter("username"); String password=request.getParameter("password"); UserManager userManager=new UserManager(); //调用业务逻辑 userManager.login(username, password); //转发 request.getRequestDispatcher("/login.jsp").forward(request, response); } }
-
-
JSP页面
-
Servlet、Jsp、MVC
-
Struts框架
- JSP页面同上
-
ActionForm页面
-
package com.bjpowernode.struts; import org.apache.struts.action.ActionForm; /** * 负责收集表单数据 * 表单属性必须与set/get,后面一致,如set 《Username》 * @author LLS * */ public class LoginActionForm extends ActionForm { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
-
-
LoginAction
-
package com.bjpowernode.struts; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; /** * 负责取得表单数据,调用业务逻辑,取得返回信息 * @author LLS * */ public class LoginAction extends Action { @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //完成转换 LoginActionForm laf=(LoginActionForm)form; //从ActionForm中取得表单数据 String username=laf.getUsername(); String password=laf.getPassword(); UserManager userManager=new UserManager(); try { userManager.login(username, password); request.setAttribute("username", username); return mapping.findForward("success"); } catch (UserNotFoundException e) { e.printStackTrace(); request.setAttribute("msg", "用户名不能找到,用户名="+username); }catch (PasswordErrorException e) { e.printStackTrace(); request.setAttribute("msg", "密码错误!"); } return mapping.findForward("error"); } }
-
-
Struts-config.xml配置信息
-
<?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"> <struts-config> <!-- 接受页面参数的页面 --> <form-beans> <form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"></form-bean> </form-beans> <!-- 页面跳转设置信息 --> <action-mappings> <action path="/login" type="com.bjpowernode.struts.LoginAction" name="loginForm" scope="request" > <forward name="success" path="/login_success.jsp"></forward> <forward name="error" path="/login_error.jsp"></forward> </action> </action-mappings> </struts-config>
-
- 从代码中可以看出,Struts页面的跳转只需要在配置文件里面配置即可,不需要在代码中写很灵活。如果是Web页面开发建议多使用框架,类似的框架也不只是Struts,它是面向请求的,还有面向时间等框架。
-
用一句搞笑的话总结框架重要性:
- 为API生,为框架死,为debug奋斗一辈子,吃符号亏,上大小写的当,最后死在需求上。