前面的文章将JSP和Servlet统统总结了一遍,接下来就要正式进入SSH的学习了。说实话,关于SSH的学习的确挺难的,三个框架,每个都要学习,最起码要做到会用吧,然后再要做到理解原理吧。这一系列的学习,是个漫长的征程。上路......
我们总是知道怎么配这个环境,但是却不知道为什么要这样配。这就涉及到Web容器加载如何加载这些Jar包了。不同的Web容器,对于如何加载Java类都是有区别的。
对于struts2的配置,我们只需要将以下几个关键的Jar包拷贝到 /WEB-INF/lib
目录下即可:
我们知道,每个Jar包都是一个压缩文件,我们可以使用压缩软件打开Jar包看看。关于Tomcat如何加载Jar包中的类文件,这里推荐一篇好文,具体可以参见这篇文章:《 图解Tomcat类加载机制 》。
将Jar包放置到正确的位置,那么当请求到达了服务器以后,那么struts2框架如何捕获这个请求,从而实现请求在struts2中流转、处理和响应呢?这就要在web.xml中配置一个Filter,将请求拦截到struts2框中,具体如下:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
通过这个struts2中的核心Filter,从而将客户端请求拦截到struts2框架中。对Filter不清楚的伙计,可以参见这篇《 Java Web Filter学习笔记 》。
先来使用struts2完成一个最简单的登陆验证Demo程序,主要用来对struts2有一个最开始的感觉。说到底,struts2框架是基于MVC分层思想来设计的,为了对每一层,每个模块最大化的进行解耦,从而实现项目的管理、开发,以及后期维护都最优化,干扰最小化;这样一来,我们学习的重点不仅仅在于如何来完成MVC这三层中的每层,更要注重的是解耦以后,这三层是如何进行关联、沟通的,只有把握了它们之间的沟通法则,也就掌握了struts2的精髓。现在通过编写这个简单的登陆验证Demo程序来熟悉Struts2。
先是前台页面,这个简单的登陆Demo程序分为以下三个前台JSP页面:
登陆页面JSP代码:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title><s:text name="loginPage" /></title> </head> <body> <s:form action="login"> <s:textfield name="userName" key="user" /> <s:password name="password" key="pass" /> <s:submit key="login" /> </s:form> </body> </html>
上面的JSP代码中使用了struts2中自定义的标签,关于JSP的自定义标签不熟悉的伙计,可以参见这篇文章:《 JSP自定义标签学习笔记 》。关于struts2中的自定义标签,后续还会进行全面的总结。
登陆成功页面只是输出一个登陆成功,代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> 登陆成功。<br/> </body> </html>
登陆失败页面如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> 用户名或密码错误,登陆失败。<br /> </body> </html>
接下来是后台Java代码,负责对用户输入的用户名和密码进行验证,代码如下:
package com.jellythink.practise; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport { 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; } public String execute() throws Exception { if (getUserName().equals("jellythink") && getPassword().equals("123456")) { ActionContext.getContext().getSession().put("user", getUserName()); return SUCCESS; } else { return ERROR; } } }
现在有了前台JSP页面,也有了后台的Java登陆处理代码;除了后台 LoginAction
类中定义的属性名和 login.jsp
中标签属性名一致以外,这个后台和前台真的就没有啥联系了。那么接下来就要说到衔接前台页面和后台的配置文件——struts.xml了。
这个struts.xml是整个struts2的关键,这个文件中配置的每一个选项都会影响着应用的运行。下面就先说说这个简单登陆验证Demo程序的struts.xml是怎样的。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="lee" extends="struts-default"> <action name="login" class="com.jellythink.practise.LoginAction"> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/success.jsp</result> </action> </package> </struts>
关于这个struts.xml具体编写规则,之后会专门进行总结。这里先简单说说,struts.xml中配置了一个名为login的action,同时指定了对应的后台处理类。当请求到达服务器以后,struts2框架通过Filter拦截用户的请求,然后通过struts.xml找到对应action的处理类,然后根据action处理类的返回结果,通过 <result .../>
标签转到其它的页面。
好了,这样就完成了一个超级简陋的登陆验证Demo程序。是的,我知道你现在依然很迷茫,很诧异,很糊涂,根本不知道我写的是什么。没关系,通过Eclipse建立一个Java Web程序,照葫芦画瓢,先将程序跑起来。后续的文章,我会一一解开你的迷惑。学习都是这样“熬”过来的。
先来简单说说MVC架构设计,在MVC架构中,Servlet作为前端中枢控制器(Controller),负责接收客户端发送过来的请求,在Servlet中只包含控制逻辑和简单的前端处理。Struts2就起了这样一个作用,为了最大程度的将Model、View和Controller这三部分进行解耦,从而提高应用的可扩展性及可维护性,struts2在这个当中占据着关键的Controller的位置,它就好比整个应用的指挥官,井井有条的打理着整个应用的运行。
对于基于struts2开发Java Web应用,我们就必须知道Struts2的工作流程,运行轨迹;对于此,先看一副图:
用户的请求到达服务器以后,被配置在web.xml中的Struts2的核心Filter所拦截:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
由于Web应用都是基于请求—响应架构的应用,所以不管哪个MVC WEB框架,都需要在web.xml中配置该框架的核心Servlet或Filter,这样才可以让该框架介入Web应用中。
定义处理用户请求的Action类;这一步是非常重要的,这里定义的Action类就是MVC中的“C”,就是所谓的控制器,该控制器负责调用Model里的方法来处理请求,对于一些非常简单的请求可以在Action中直接处理。
Struts2根据对应的请求,在struts.xml中找到对应的Action处理类:
<action name="login" class="com.jellythink.practise.LoginAction"> ... </action>
关于struts.xml配置文件的编写,这又是一个复杂的题目,后续文章会总结。找到了对应的Action处理类以后,就会调用对应的 execute
方法,至于为什么调用 execute
方法,而不是其它方法,后续文章会说,请关注。
Action根据业务返回结果,返回对应的逻辑视图名,例如下列代码中的 return SUCCESS
和 return ERROR
:
public String execute() throws Exception { if (getUserName().equals("jellythink") && getPassword().equals("123456")) { ActionContext.getContext().getSession().put("user", getUserName()); return SUCCESS; } else { return ERROR; } }
这里的SUCCESS和ERROR都是字符串常量,对应的是:success和error,对于为什么这样定义,后续的文章还会继续总结。
Struts2根据Action返回的逻辑视图名,在配置文件中对应物理视图资源,例如:
<action name="login" class="com.jellythink.practise.LoginAction"> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/success.jsp</result> </action>
当Action控制器返回input字符串时,则进入 /login.jsp
页面;当返回error字符串时,则进入 /error.jsp
页面;当返回success字符串时,则进入 /success.jsp
页面。就是通过这种方法,将View和Controller进行解耦。
服务器将对应的页面响应给用户,从而完成一次请求—响应。这就是关于Struts2的整体开发流程。
虽然几句话就把Struts2的整体开发流程总结了一遍,但是这里面还有很多东西没有说清楚,需要后续大量的文章来总结,我会通过后续的文章,对Struts2进行抽丝剥茧,将整个Struts2的开发过程呈现在大家面前。
学习功夫,先学招式,再学精髓;学习编程亦是如此。先从整体上了解这个东西,然后再从局部着手研究这个东西,时刻知道自己所处的位置。从我的个人学习来说,学习一个东西,千万不可一开始就扎进某个知识细节里面,这样反而会拣了芝麻丢了西瓜,个人观点,仅供参考。
果冻想,认真玩技术的地方。
2015年12月29日 于呼和浩特。