转载

Struts2学习之初见Struts2

前言

前面的文章将JSP和Servlet统统总结了一遍,接下来就要正式进入SSH的学习了。说实话,关于SSH的学习的确挺难的,三个框架,每个都要学习,最起码要做到会用吧,然后再要做到理解原理吧。这一系列的学习,是个漫长的征程。上路......

从安装配置说起

我们总是知道怎么配这个环境,但是却不知道为什么要这样配。这就涉及到Web容器加载如何加载这些Jar包了。不同的Web容器,对于如何加载Java类都是有区别的。

对于struts2的配置,我们只需要将以下几个关键的Jar包拷贝到 /WEB-INF/lib 目录下即可:

  • xwork-core-2.3.24.1.jar
  • struts2-core-2.3.24.1.jar
  • ognl-3.0.6.jar
  • javassist-3.11.0.GA.jar
  • commons-io-2.2.jar
  • commons-lang3-3.2.jar
  • commons-fileupload-1.3.1.jar
  • freemarker-2.3.22.jar

我们知道,每个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学习笔记 》。

一个Demo小样

先来使用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程序,照葫芦画瓢,先将程序跑起来。后续的文章,我会一一解开你的迷惑。学习都是这样“熬”过来的。

Struts2开发流程

先来简单说说MVC架构设计,在MVC架构中,Servlet作为前端中枢控制器(Controller),负责接收客户端发送过来的请求,在Servlet中只包含控制逻辑和简单的前端处理。Struts2就起了这样一个作用,为了最大程度的将Model、View和Controller这三部分进行解耦,从而提高应用的可扩展性及可维护性,struts2在这个当中占据着关键的Controller的位置,它就好比整个应用的指挥官,井井有条的打理着整个应用的运行。

对于基于struts2开发Java Web应用,我们就必须知道Struts2的工作流程,运行轨迹;对于此,先看一副图:

Struts2学习之初见Struts2

  1. 用户通过浏览器访问Java Web应用
  2. 用户的请求到达服务器以后,被配置在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应用中。

  3. 定义处理用户请求的Action类;这一步是非常重要的,这里定义的Action类就是MVC中的“C”,就是所谓的控制器,该控制器负责调用Model里的方法来处理请求,对于一些非常简单的请求可以在Action中直接处理。

    Struts2根据对应的请求,在struts.xml中找到对应的Action处理类:

    <action name="login" class="com.jellythink.practise.LoginAction">
        ...
    </action>

    关于struts.xml配置文件的编写,这又是一个复杂的题目,后续文章会总结。找到了对应的Action处理类以后,就会调用对应的 execute 方法,至于为什么调用 execute 方法,而不是其它方法,后续文章会说,请关注。

  4. Action根据业务返回结果,返回对应的逻辑视图名,例如下列代码中的 return SUCCESSreturn 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,对于为什么这样定义,后续的文章还会继续总结。

  5. 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进行解耦。

  6. 服务器将对应的页面响应给用户,从而完成一次请求—响应。这就是关于Struts2的整体开发流程。

虽然几句话就把Struts2的整体开发流程总结了一遍,但是这里面还有很多东西没有说清楚,需要后续大量的文章来总结,我会通过后续的文章,对Struts2进行抽丝剥茧,将整个Struts2的开发过程呈现在大家面前。

总结

学习功夫,先学招式,再学精髓;学习编程亦是如此。先从整体上了解这个东西,然后再从局部着手研究这个东西,时刻知道自己所处的位置。从我的个人学习来说,学习一个东西,千万不可一开始就扎进某个知识细节里面,这样反而会拣了芝麻丢了西瓜,个人观点,仅供参考。

果冻想,认真玩技术的地方。

2015年12月29日 于呼和浩特。

原文  https://www.jellythink.com/archives/252
正文到此结束
Loading...