Struts 2基础

struts2基本类库 立即下载

 

第2章 Struts 2

此内容是《Java Web开发教程——入门与提高篇(JSP+Servlet)》一书附赠资料的一部分。

2.1概述

Struts现在分两个版本:Struts 1.X和Struts 2.X。Struts 1.X已经有很多年了,可以说非常流行,但是因为其他框架的快速发展以及自身存在的问题,Struts 2诞生了,Struts 2与Struts 1的区别非常大,实际上Struts 2的核心思想是基于另外一个非常成功的Web框架WebWork。两者的区别如表20.1所示。下面主要针对Struts 2进行介绍。

表2.1 Struts1和Struts2的比较

Feature

Struts 1

Struts 2

Action类

在Struts 1中要求Action类继承抽象的基类。在Struts 1中一个普遍存在的问题就是面向抽象类编程,而不是面向接口编程。

Struts 2中的Action可以实现一个Action接口,同时可以实现其他的接口,这样可以使用户有选择性地使用其它自定义的服务。Struts 2提供了基础类ActionSupport,该类实现了一些通用的接口。Action接口不是必须的。任何具有execute方法的POJO对象都可以用作Struts 2的Action对象。

线程模型

Struts 1的Actions是单例的,因为只有一个类的实例来处理所有对这个Action的请求,所以必须是线程安全的。单例策略对Struts 1的Action的能够完成的功能有很大限制,有些功能需要额外的努力才能完成。Action资源必须是线程安全的或者synchronized

Struts 2的Action对象是为每个请求实例化的,因此没有线程安全的问题。(在实践中,Servlet容器会为每个请求生成多个throw-away对象,增加的对象不会对性能产生太大影响或者对垃圾回收产生影响)

Servlet依赖

Struts 1的Action依赖Servlet API,因为当调用Action的execute方法时需要传参数HttpServletRequest和HttpServletResponse。

Struts 2的Action与容器不是紧密结合在一起的。多数情况下,servlet上下文被表示为Map对象,允许对Action进行独立的测试。如果需要,Struts 2的Action仍然可以访问原始的request和response对象。 然而,其它框架元素可以减少或者消除对HttpServetRequest和 HttpServletResponse对象进行直接访问的必要。

可测试性

测试Struts 1 Action的一个主要障碍就是execute方法使用了Servlet API。1个第三方扩展Struts TestCase,为Struts 1提供了一组模拟(mock)对象。

Struts 2的Action可以通过实例化、设置属性和调用方法进行测试。依赖注入支持使测试更简单。

获取输入

Struts 1使用ActionForm对象来获取输入。像Action一样,所有的ActionForm必须继承一个基类。因为其它的JavaBean不能用作ActionForm,开发人员经常需要创建多余的类来获取输入。可以使用动态Form来替换传统的ActionForm类,但是开发人员同样可能需要重新描述已有的JavaBean。

Struts 2使用Action的属性作为输入属性,不用创建第二个输入对象。输入属性可以是复杂的对象类型,还可以有自己的属性。可以在页面中通过taglib访问Action属性。Struts 2也支持ActionForm模式,以及POJO表单对象和POJO Action。复杂对象类型,包括业务或者域对象,都可以作为输入/输出对象。模型驱动的特性简化了标签库对POJO输入对象的引用。

表达式语言

Struts 1集成了JSTL,所以可以使用JSTL的EL语言,EL提供了基本的对象结构遍历(object graph traversal),但是集合以及索引属性支持比较弱。

Struts 2可以使用JSTL,同时Struts还支持另外一种功能更强大、使用更灵活的表达式语言,这种语言是Object Graph Notation Language,简称 OGNL。

值与视图的绑定

Struts 1使用了标准的JSP机制把对象与要访问的页面上下文绑定。

Struts 2使用了一种ValueStack技术,这样标签库不用把视图与要呈现的对象类型关联就可以访问值。ValueStack策略允许重用涉及多个类型的视图,这些类型可能有相同的属性名,但是属性类型不同。

类型转换

Struts 1的ActionForm属性通常都是字符串类型。Struts 1 使用Commons-Beanutils进行类型转换。转换器是针对每个类的,而不能为每个实例配置。

Struts 2使用OGNL进行类型转换,框架包含了常用对象类型和基本数据类型的转换器。

验证

Struts 1支持手动验证,通过ActionForm的validate方法或者通过继承通用的验证器来完成。对于同一个类可以有不同的验证上下文环境,但是不能链接到对子类型的验证。

Struts 2支持通过验证方法进行手工验证和XWork验证框架。Xwork验证框架支持对子属性的链接验证,使用为属性类型定义的验证规则和上下文。

Action执行的控制

Struts 1支持为每个模块提供独立的请求处理器(生命周期),但是同一个模块中的所有Action具有相同的生命周期。

Struts 2通过拦截器栈支持为每个Action创建不同的生命周期。必要的时候,可以使用不同的Actio创建和使用自定义栈。

注:来自Struts的官方网站:http://struts.apache.org/2.0.11.2/docs/comparing-struts-1-and-2.html

Strust 2结构图如图2.1(原图来自Strust 2文档)所示:

图2.1 Struts2结构图

在处理一个请求的时候,主要使用3个类:Action、Interceptor和Result

处理流程:

u  请求到达服务器之后,首先经过一系列过滤器,有的是可选的,最主要的过滤器是FilterDispatcher。所有的请求都会提交给它处理,该过滤器是在web.xml中配置的。配置代码如下:

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

    </filter>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

u  FilterDispatcher过滤器接收到请求之后调用ActionMapper查看是否需要调用Action。ActionMapper提供了HttpRequest与Action调用请求之间的映射关系,可以决定当前请求是否需要调用Action。如果ActionMapper返回的信息表明需要调用Action。FilterDispatcher过滤器把控制前交给ActionProxy;

u  ActionProxy调用配置文件管理器ConfigurationManager,该管理器从struts.xml配置文件中获取配置信息,获取的信息主要包括当前请求对应哪个Action(对用户的请求进行处理),对应哪些Result(决定了如何对用户响应),有时候还涉及拦截器。然后根据这些信息创建ActionInvocation对象,该对象负责具体的调用过程。struts.xml是用户需要提供的最主要的配置文件。下面是一个struts.xml配置文件的部分内容。

<struts>

    <package name="default" extends="struts-default">

 

        <action name="Logon" class="mailreader2.Logon">

            <result name="input">/pages/Logon.jsp</result>

            <result name="cancel" type="redirectAction">Welcome</result>

            <result type="redirectAction">MainMenu</result>

            <result name="expired" type="chain">ChangePassword</result>

        </action>

 

        <action name="Logoff" class="mailreader2.Logoff">

            <result type="redirectAction">Welcome</result>

        </action>

 

    </package>

</struts>

u  ActionInvocation对象按照顺序执行当前请求所对应的拦截器,拦截器能够对请求进行预处理,例如验证、文件上传等,并能够对响应内容进行再处理。通常拦截器是由系统提供的,如果需要,编程人员只需要进行配置即可。在调用Action的方法之前,会调用拦截器的预处理方法;

u  ActionInvocation对象调用拦截器的预处理方法之后会调用Action的execute方法,Action中的代码主要由编程人员根据功能进行编写的,通常从数据库检索信息或者向数据库存储信息。Action的方法返回一个字符串。下面是一个简单的Action例子。

package simple;

import java.util.Map;

import javax.servlet.http.HttpSession;

 

import com.opensymphony.webwork.ServletActionContext;

import com.opensymphony.xwork.ActionSupport;

 

public class LogoutAction extends ActionSupport {

 

    public String execute() throws Exception {

     Map session = ActionContext.getContext().getSession();

     session.remove("logined");

     session.remove("context");

        return SUCCESS;

    }

 

}

u  ActionInvocation对象根据Action方法的返回结果以及struts配置文件生成Result对象。Result对象选择一个模板文件来响应用户,模板文件可以是JSP、FreeMarker和Velocity。

u  容器加载并执行模板文件,使用在Action中获取的信息对模版中的变量进行赋值,也可能从资源文件或者其他内部对象中获取信息。最终向浏览器呈现的是HTML、PDF或者其他内容。

u  模板文件执行的结果会经过拦截器进行再处理,最后通过过滤器返回给客户端。

在该结构图中,既包含了Struts框架提供的基础接口,也包括了用户要编写的文件。其中,ActionMapper、ActionProxy、ConfigurationManager、ActionInvocation和Result是框架提供的核心类。过滤器和拦截器是框架提供的,用户可以根据需要进行配置,当然也可以编写自己的过滤器和拦截器。用户需要编写的文件是struts.xml、Action和模板文件,这些也是用户在使用Struts 2框架时需要做的工作。

2.2 开发人员的主要任务

框架为开发人员提供了大量的辅助类,用户在使用框架开发的时候只需要编写很少文件。在使用Struts 2开发的时候,首先应该把环境搭建起来,然后使用Struts 2提供的标签开发界面,然后编写Action类,最后进行配置。

环境搭建

在进行具体的开发之前,需要先搭建环境。包括如下过程:

u  创建Web工程;

u  加载Struts 2的核心类库,核心类库包括commons-logging-1.0.4.jar、freemarker-2.3.8.jar、ognl-2.6.11.jar、struts2-core-2.0.11.2.jar和xwork-2.0.5.jar,把这些类库放到Web工程的WEB-INF/lib下面;

u  配置web.xml,主要配置Struts中心控制器FilterDispatcher,下面是1个例子。

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 

    <display-name>Struts Blank</display-name>

 

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

    </filter>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

 

    <welcome-file-list>

        <welcome-file>index.html</welcome-file>

    </welcome-file-list>

 

</web-app>

u  创建struts.xml配置文件,与类文件放在一起,空白的struts文件如下所示。在使用Struts 2进行开发所有的配置基本上都在这个文件中完成。也可以根据需要创建多个配置文件,然后在这个配置文件中使用<include file="example.xml"/>进行包含。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

 

<struts>

 

    <constant name="struts.enable.DynamicMethodInvocation" value="false" />

    <constant name="struts.devMode" value="false" />

 

    <include file="example.xml"/>

 

    <!-- Add packages here -->

 

</struts>

环境搭建完之后,在具体开发过程中主要完成3个方面的工作:

u  制作模板文件,可以使用JSP、FreeMarker或者Velocity等;

u  编写Action,基本上每个动作对应1个Action;

u  配置,主要在struts.xml中进行配置。

下面分别介绍。

制作模板文件

模版文件的主要作用是接收用户输入的信息,并向用户展示信息。Struts提供了多个标签库来简化页面的代码量,使用标签之后页面也更容易维护。下面是一段标签:

<s:actionerror/>

<s:form action="Profile_update" validate="true">

  <s:textfield label="Username" name="username"/>

  <s:password label="Password" name="password"/>

  <s:password label="(Repeat) Password" name="password2"/>

  <s:textfield label="Full Name" name="fullName"/>

  <s:textfield label="From Address" name="fromAddress"/>

  <s:textfield label="Reply To Address" name="replyToAddress"/>

  <s:submit value="Save" name="Save"/>

  <s:submit action="Register_cancel" value="Cancel" name="Cancel"

            onclick="form.onsubmit=null"/>

</s:form>

Struts 2中提供了两类通用标签和3类界面标签:

u  控制标签

u  数据标签

u  Form标签

u  Non-Form用户接口标签

u  Ajax标签

下面对这些类型的标签进行介绍。

控制标签及其用法如表2.2所示。

表2.2 控制标签

标签名

描述

例子

if

与Java中的if基本相同

<s:if test="%{false}">

    <div>Will Not Be Executed</div>

</s:if>

<s:elseif test="%{true}">

    <div>Will Be Executed</div>

</s:elseif>

<s:else>

    <div>Will Not Be Executed</div>

</s:else>

else if

与Java中的else if基本相同

else

与Java中的else基本相同

append

按照顺序把多个迭代器的元素组合到一个迭代器中,保持原来的顺序不变。

<s:append var="myAppendIterator">

     <s:param value="%{myList1}" />

     <s:param value="%{myList2}" />

     <s:param value="%{myList3}" />

</s:append>

<s:iterator value="%{#myAppendIterator}">

     <s:property />

</s:iterator>

generator

根据val属性的给定的值生成迭代器对象。

<s:generator val="%{'aaa,bbb,ccc,ddd,eee'}">

 <s:iterator>

     <s:property /><br/>

 </s:iterator>

</s:generator>

iterator

对迭代器或者集合进行遍历,类似于Java中的for-each循环。

<s:iterator value="#it.days" status="rowstatus">

  <tr>

    <s:if test="#rowstatus.odd == true">

      <td style="background: grey"><s:property/></td>

    </s:if>

    <s:else>

      <td><s:property/></td>

    </s:else>

  </tr>

</s:iterator>

merge

把多个迭代器的元素合并到一个迭代器中,合并后的顺序为1.1,2.1,3.1,1.2,1.3…,1.1表示第1个迭代器的第1个元素。

<s:merge var="myMergedIterator1">

     <s:param value="%{myList1}" />

     <s:param value="%{myList2}" />

     <s:param value="%{myList3}" />

</s:merge>

<s:iterator value="%{#myMergedIterator1}">

     <s:property />

</s:iterator>

sort

对List进行排序。

<s:sort var="mySortedList" comparator="myComparator" source="myList" />

subset

获取集合的子集。

<s:subset var="mySubset" source="myList" count="13" start="3" />

数据标签及其用法如表2.3所示。

表2.3 数据标签

标签名

描述

例子

a

生成HTML的<a>

<s:a href="%{testUrlId}"><img src="<s:url

value="/images/delete.gif"/>" border="none"/></s:a>

action

在JSP页面中直接调用Action

<s:action name="actionTagAction" executeResult="true" />

bean

实例化JavaBean对象

<s:bean name="org.apache.struts2.example.counter.SimpleCounter" var="counter">

  <s:param name="foo" value="BAR" />

  The value of foot is : <s:property value="foo"/> <br />

</s:bean>

date

创建Date对象

<s:date name="person.birthday" format="dd/MM/yyyy" />

debug

 

 

i18n

得到ResourceBundle对象。

<s:i18n name="myCustomBundle">

</s:i18n>

include

包含1个JSP或者Servlet的输出。

<s:include value="myJsp.jsp">

   <s:param name="param1" value="value2" />

</s:include>

param

为其他标签提供参数

参考上面的例子

property

获取属性值

参考bean标签的例子

push

把值保存起来使用

<s:push value="user">

    <s:propery value="firstName" />

    <s:propery value="lastName" />

</s:push>

set

把某个值保存到某个作用范围的变量中。

<s:set name="personName" value="person.name"/>

Hello, <s:property value="#personName"/>. How are you?

text

呈现i18n的文本消息

<s:i18n name="struts.action.test.i18n.Shop">

    <s:text name="main.title"/>

</s:i18n>

url

用于生成URL

<s:url value="editGadget.action">

    <s:param name="id" value="%{selected}" />

</s:url>

Form标签及其用法如表2.4所示。

表2.4 Form标签

标签名

描述

例子

checkbox

生成复选框

<s:checkbox label="checkbox test" name="checkboxField1"

value="aBoolean" fieldValue="true"/>

checkboxlist

生成多个复选框

<s:checkboxlist name="foo" list="bar"/>

combobox

输入框与下拉框的组合。

<s:combobox

    label="My Favourite Fruit"

    name="myFavouriteFruit"

    list="{'apple','banana','grape','pear'}"

    headerKey="-1"

    headerValue="--- Please Select ---"

    emptyOption="true"

    value="banana" />

doubleselect

生成联动菜单

<s:doubleselect label="doubleselect test1" name="menu"

list="{'fruit','other'}" doubleName="dishes"

doubleList="top == 'fruit' ? {'apple', 'orange'} : {'monkey', 'chicken'}" />

head

生成HTML的head部分。

<head>

  <title>My page</title>

  <s:head/>

</head>

file

生成文件输入框

<s:file name="anUploadFile" accept="text/*" />

 

form

生成form表单

<p/>

<s:form ... />

<p/>

hidden

生成隐藏域

<s:hidden name="foo" value="bar" />

label

生成标签

<s:label key="userName" />

optiontrans

-ferselect

生成两个列表框,可以通过中间的按钮把左边的选项移动到右边,也可以把右边的选项移动到左边。

<s:optiontransferselect

     label="Favourite Cartoons Characters"

     name="leftSideCartoonCharacters"

     list="{'Popeye', 'He-Man', 'Spiderman'}"

     doubleName="rightSideCartoonCharacters"

     doubleList="{'Superman', 'Mickey Mouse', 'Donald Duck'}"

 />

optgroup

在select中提供选项

<s:select label="My Selection"

           name="mySelection"

           value="%{'POPEYE'}"

           list="%{#{'SUPERMAN':'Superman', 'SPIDERMAN':'spiderman'}}">

   <s:optgroup label="Adult"

                list="%{#{'SOUTH_PARK':'South Park'}}" />

   <s:optgroup label="Japanese"

                list="%{#{'POKEMON':'pokemon','DIGIMON':'digimon',

'SAILORMOON':'Sailormoon'}}" />

</s:select>

select

生成下拉框

password

密码输入框

<s:password label="%{text('password')}" name="password"

size="10" maxlength="15" />

radio

单选按钮

<s:radio label="Gender" name="male" list="#genders.genders"/>

reset

重值按钮

<s:reset value="Reset" />

submit

提交按钮

<s:submit value="OK" />

textarea

生成文本域

<s:textarea label="Comments" name="comments" cols="30" rows="8"/>

textfield

生成输入框

<s:textfield key="user" />

 

token

阻止表单重复提交

<s:textfield key="user" />

 

updownselect

创建元素能够上下移动的列表框

<s:updownselect

list="#{'england':'England', 'america':'America', 'germany':'Germany'}"

name="prioritisedFavouriteCountries"

headerKey="-1"

headerValue="--- Please Order Them Accordingly ---"

emptyOption="true" />

non-form UI标签及其用法如表2.5所示。

表2.5 non-form标签

标签名

描述

例子

actionerror

呈现错误信息

<s:actionerror />

actionmessage

呈现提示信息

<s:actionmessage />

component

创建自定义组件

<s:component template="/my/custom/component.vm"/>

div

生成HTML <div>

 

fielderror

输出关于输入元素的错误信息

   <s:fielderror>

        <s:param>field1</s:param>

        <s:param>field2</s:param>

   </s:fielderror>

   <s:form .... >

      ....

   </s:form>

Ajax标签包括a、autocompleter、bind、datetimepicker、div、head、submit、tabbedpanel、textarea、tree、treenode等。具体用法参考Struts 2帮助文档。

编写Action

针对每个功能可以编写1个Action,也可以多个功能共享1个Action。Action完成的主要功能包括:

u  获取用户的输入信息,这个获取的过程是由框架完成的,但是用户需要在Action中定义与用户输入表单元素名字相同的成员变量,关键是要提供对成员变量赋值的set方法,这样框架在获取用户输入信息之后会调用set方法把值赋给Action的成员变量。

u  根据用户的请求信息,调用完成业务逻辑的JavaBean。如果希望要把某些执行结果传递给模板文件(JSP、FreeMarker和Velocity等),需要在Action中定义成员变量来表示这些结果,最关键的是要定义get方法,这样在执行模版文件的时候会通过get方法来获取这些信息。

u  根据执行的结果,返回1个字符串,这个字符串决定了使用什么模板对用户进行响应。

下面是1个简单的例子。

public class LoginAction extends ActionSupport {

 

    private String userId;

    private String passwd;

    // 对userId和passwd操作的setter和getter方法

    public String execute() throws Exception {

        if ("admin".equals(userId) && "password".equals(passwd)) {

            Map session = ActionContext.getContext().getSession();

            session.put("logined","true");

            session.put("context", new Date());

            return SUCCESS;

        }

        return ERROR;

    }

}

注意:并不是必须继承ActionSupport,主要提供execute方法即可。

配置

通过配置文件Struts.xml对Web应用的流程进行管理,包括Action映射和Result处理,前者把请求与Action关联起来,后者把Action执行的结果与响应界面关联起来。下面是一段配置。下面是一个简单的例子。

<struts>

    <package name="default" extends="struts-default">

 

        <action name="Logon" class="mailreader2.Logon">

            <result name="input">/pages/Logon.jsp</result>

            <result name="cancel" type="redirectAction">Welcome</result>

            <result type="redirectAction">MainMenu</result>

            <result name="expired" type="chain">ChangePassword</result>

        </action>

 

        <action name="Logoff" class="mailreader2.Logoff">

            <result type="redirectAction">Welcome</result>

        </action>

 

    </package>

</struts>

Struts 2中完成的主要配置如表2.6所示。

表2.6 Struts 2的主要配置信息

配置元素

例子

JavaBean

<bean type="com.opensymphony.xwork2.ObjectFactory"

name="myfactory" class="com.company.myapp.MyObjectFactory" />

常量

<constant name="struts.devMode" value="true" />

包

<package name="employee" extends="struts-default" namespace="/employee">

   ...

</package>

命名空间

包含

<include file="Home.xml"/>

拦截器

<interceptors>

  <interceptor name="security"

 class="com.company.security.SecurityInterceptor"/>

  <interceptor-stack name="secureStack">

    <interceptor-ref name="security"/>

    <interceptor-ref name="defaultStack"/>

  </interceptor-stack>

</interceptors>

引用拦截器

<action name="VelocityCounter"

class="org.apache.struts2.example.counter.SimpleCounter">

    <result name="success">...</result>

    <interceptor-ref name="defaultComponentStack"/>

</action>

全局Result:

<global-results>

    <result name="error">/Error.jsp</result>

    <result name="invalid.token">/Error.jsp</result>

</global-results>

Action

Result

异常配置

在Action中使用:

<exception-mapping exception="com.company.SecurityException" result="login"/>

全局:

<global-exception-mappings>

<exception-mapping exception="java.sql.SQLException" result="SQLException"/>

<exception-mapping exception="java.lang.Exception" result="Exception"/>

</global-exception-mappings>

Struts 2提供了大量的拦截器,用户可以根据需要调用。

Struts 2的配置文件struts.xml的DTD定义如下。

<!--

   Struts configuration DTD.

   Use the following DOCTYPE

  

   <!DOCTYPE struts PUBLIC

          "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

          "http://struts.apache.org/dtds/struts-2.0.dtd">

-->

 

<!ELEMENT struts (package|include|bean|constant)*>

 

<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>

<!ATTLIST package

    name CDATA #REQUIRED

    extends CDATA #IMPLIED

    namespace CDATA #IMPLIED

    abstract CDATA #IMPLIED

    externalReferenceResolver NMTOKEN #IMPLIED

> 

 

<!ELEMENT result-types (result-type+)>

 

<!ELEMENT result-type (param*)>

<!ATTLIST result-type

    name CDATA #REQUIRED

    class CDATA #REQUIRED

    default (true|false) "false"

> 

 

<!ELEMENT interceptors (interceptor|interceptor-stack)+>

 

<!ELEMENT interceptor (param*)>

<!ATTLIST interceptor

    name CDATA #REQUIRED

    class CDATA #REQUIRED

> 

 

<!ELEMENT interceptor-stack (interceptor-ref*)>

<!ATTLIST interceptor-stack

    name CDATA #REQUIRED

> 

 

<!ELEMENT interceptor-ref (param*)>

<!ATTLIST interceptor-ref

    name CDATA #REQUIRED

> 

 

<!ELEMENT default-interceptor-ref (param*)>

<!ATTLIST default-interceptor-ref

    name CDATA #REQUIRED

> 

 

<!ELEMENT default-action-ref (param*)>

<!ATTLIST default-action-ref

    name CDATA #REQUIRED

> 

 

<!ELEMENT default-class-ref (param*)>

<!ATTLIST default-class-ref

    class CDATA #REQUIRED

> 

 

<!ELEMENT global-results (result+)>

 

<!ELEMENT global-exception-mappings (exception-mapping+)>

 

<!ELEMENT action (param|result|interceptor-ref|exception-mapping)*>

<!ATTLIST action

    name CDATA #REQUIRED

    class CDATA #IMPLIED

    method CDATA #IMPLIED

    converter CDATA #IMPLIED

> 

 

<!ELEMENT param (#PCDATA)>

<!ATTLIST param

    name CDATA #REQUIRED

> 

 

<!ELEMENT result (#PCDATA|param)*>

<!ATTLIST result

    name CDATA #IMPLIED

    type CDATA #IMPLIED

> 

 

<!ELEMENT exception-mapping (#PCDATA|param)*>

<!ATTLIST exception-mapping

    name CDATA #IMPLIED

    exception CDATA #REQUIRED

    result CDATA #REQUIRED

> 

 

<!ELEMENT include (#PCDATA)>

<!ATTLIST include

    file CDATA #REQUIRED

> 

 

<!ELEMENT bean (#PCDATA)>

<!ATTLIST bean

    type CDATA #IMPLIED

    name CDATA #IMPLIED

    class CDATA #REQUIRED

    scope CDATA #IMPLIED

    static CDATA #IMPLIED

    optional CDATA #IMPLIED

> 

 

<!ELEMENT constant (#PCDATA)>

<!ATTLIST constant

    name CDATA #REQUIRED

    value CDATA #REQUIRED   

> 

2.3实例

功能:登录。

涉及的文件有:

l  Login.jsp,用于输入登录信息;

l  welcome.jsp,登录之后的欢迎界面;

l  loginCheck.jsp,判断用户是否登录;

l  LoginAction.java,完成登录业务处理,正常情况下会调用其他业务逻辑JavaBean来完成;

l  LogoutAction.java,完成退出业务处理;

l  struts.xml,应用的配置文件。

下面分别介绍。

Login.jsp

源文件:Login.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

 pageEncoding="ISO-8859-1"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

</head><body>

<form action="login.action" method="post">

User id<input type="text" name="userId" /> <br/>

Password <input type="password" name="passwd" /> <br />

<input type="submit" value="Login"/>

</form>

</body>

</html> 

/pages/welcome.jsp 

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

<%@ taglib prefix="ww" uri="/webwork" %>

<jsp:include page="WEB-INF/inc/loginCheck.jsp" />

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Welcome</title>

</head>

 

<body>Welcome, you have logined. <br />

The attribute of 'context' in session is

<ww:property value="#session.context" />

<br /><br /><br />

<a xhref="<%= request.getContextPath() %>/logout.action">Logout</a>

<br />

<a xhref="<%= request.getContextPath() %>/logout2.action">Logout2</a>

</body>

</html> 

/WEB-INF/inc/loginCheck.jsp

<%@ taglib="/webwork" prefix="ww" %>
<ww:if test="#session.login != 'true'">
<jsp:forward page="<%= request.getContextPath() %>/login.jsp" />
</ww:if>
 

simple.LoginAction.java

package simple;

import java.util.Date;import java.util.Map;

 

import javax.servlet.http.HttpSession;

 

import com.opensymphony.webwork.ServletActionContext;

import com.opensymphony.xwork.ActionSupport;

 

public class LoginAction extends ActionSupport {

 

    private String userId;

    private String passwd;

 

    public String execute() throws Exception {

        if ("admin".equals(userId) && "password".equals(passwd)) {

//            HttpSession session = ServletActionContext.getRequest().getSession();

//            session.setAttribute("logined","true");

//            session.setAttribute("context", new Date());

// Better is using ActionContext

  Map session = ActionContext.getContext().getSession();

session.put("logined","true");

            session.put("context", new Date());

            return SUCCESS;

        }

        return ERROR;

    }

 

    public String logout() throws Exception {

//        HttpSession session = ServletActionContext.getRequest().getSession();

//        session.removeAttribute("logined");

//        session.removeAttribute("context");

 Map session = ActionContext.getContext().getSession();

 session.remove("logined");

        session.remove("context");

        return SUCCESS;

    }

 

    public String getPasswd() {

        return passwd;

    }

 

    public void setPasswd(String passwd) {

        this.passwd = passwd;

    }

 

    public String getUserId() {

        return userId;

    }

 

    public void setUserId(String userId) {

        this.userId = userId;

    }

}

 simple.LogoutAction.java

package simple;

import java.util.Map;

import javax.servlet.http.HttpSession;

 

import com.opensymphony.webwork.ServletActionContext;

import com.opensymphony.xwork.ActionSupport;

 

public class LogoutAction extends ActionSupport {

 

    public String execute() throws Exception {

     Map session = ActionContext.getContext().getSession();

session.remove("logined");

session.remove("context");

        return SUCCESS;

    }

 

} 

 /WEB-INF/classes/xwork.xml

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">

 

<xwork>

    <include file="webwork-default.xml"/>

 

    <package name="default" extends="webwork-default">

        <!-- Add your actions here -->

        <action name="login" class="simple.LoginAction" >

            <result name="success" type="dispatcher">/pages/welcome.jsp</result>

            <result name="error" type="redirect">/login.jsp</result>

        </action>

 

        <action name="logout2" class="simple.LoginAction" method="logout" >

            <result name="success" type="redirect">/login.jsp</result>

        </action>

 

        <action name="logout" class="simple.LogoutAction" >

            <result name="success" type="redirect">/login.jsp</result>

        </action>

    </package>

</xwork>

struts2最常用的几个类库 初学者经常会为加struts类库感到迷茫。本人自己将最常用的类库打包。希望能帮到大家! 立即下载

相关推荐

Python xlwings报错解决:从‘NoneType‘到完美运行WPS表格的完整指南

本文深入解析了使用Python xlwings库自动化WPS表格时遇到的经典'NoneType'报错(AttributeError: 'NoneType' object has no attribute 'apps')的根源与解决方案。核心在于pywin32版本与WPS的兼容性问题,文章提供了从版本降级、依赖管理到构建健壮自动化环境的完整实战指南,帮助开发者彻底解决兼容性难题,实现稳定运行。

n4o5p6q7r的博客 303

struts2中的几个基础类

1、Action类定义了几个常量public interface Action{ public static final String SUCESS = "success"; public static final String ERROR = "error"; public static final String NONE = "none"; public static final String...

weixin_30538029的博客 307

CTF-Web习题:2019强网杯 UPLOAD

本题涉及知识点:代码审计、文件上传漏洞、反序列化漏洞

LJW123487的博客 1903

Struts 2 完整类库  以及配置解析

完整类库列表 下载地址:http://struts.apache.org/ antlr-2.7.2.jar commons-beanutils-1.6.jar commons-chain-1.1.jar commons-logging-1.0.4.jar commons-logging-api-1.1.jar commons-validator-1.3.0.jar freemarker-2.3.

小李子不是我 1063

10xGenomics官方可视化工具——Loupe Browser

Loupe Browser是⼀款10xGenomics开发的交互式桌⾯应⽤程序,⽤于探索10x单细胞数据,可以用来找出感兴趣的细胞、找出显著差异表达的基因、鉴定细胞类型、探索细胞亚类和数据共享。

weixin_47195452的博客 3361

使用lightGBM进行数据建模及预测

在机器学习领域中,数据建模和预测一直是非常重要的任务。而lightGBM作为一种基于梯度提升算法的高效机器学习框架,被广泛应用于数据建模和预测中。本文将介绍如何使用lightGBM进行数据建模和预测。到此,我们已经成功使用lightGBM对数据进行了建模和预测。使用lightGBM可以快速、高效地完成数据建模和预测任务,是机器学习领域中不可或缺的工具之一。使用lightGBM进行数据建模及预测。

qq_37934722的博客 1018

Struts2基础总结-入门篇

Struts2基础总结-入门篇一、Struts2环境搭建 在web项目的WEB—IFN/lib目录下导入所需的jar包 可在Struts2的示例项目中的Copy 在web.xml中配置Struts2的Filter <!-- 配置Struts 2框架的核心Filter --> <filter> <!--过滤器名 --> <filter-name>struts2</filt

Leven.Chen的专栏 524

【一看就会】Autoware.universe的“规划”部分源码梳理【0】——Planning综述(持续更新中)

单独开一篇planning综述,作为整个规划系列的开篇。本篇综述会持续更新,希望能帮助大家更好的整体理解规划部分。这个部分会持续更新。

weixin_48386130的博客 1966

Struts2 基础入门

什么是Struts2 Struts2 是 Apache 软件组织推出的一个基于 MVC 模式的轻量级 Web 框架,自问世以来,就受到了广大 Web 开发者的欢迎。目前,Struts2 在 Java Web 开发领域中已占据了十分重要的地位。 目前为止,Struts 框架拥有两个主要版本:Struts1.x 和 Struts2.x。Struts1 是最早的基于 MVC 模式的轻量级 Web 框架,它能够合理划分代码结构,并包含验证框架、国际化框架等多种实用工具框架。 随着技术的不断进步,Struts1 的局

李鲤驴的博客 1743

Unity与iOS原生交互实战指南

C#(DllImport) → C 接口(extern "C") → Objective‑C / SwiftObjective‑C → UnitySendMessage → C#(GameObject + public 方法)在写.mm文件;在里面写;C# 用声明;调用它,参数就是 string / 数值等;在.mm里做你想做的 iOS 原生操作。在 Unity 里准备一个常驻 GameObject,比如;上面挂一个脚本,写;在 iOS 插件中用;

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1357

MATLAB基础应用精讲-【数模应用】信用评分模型(附R语言和python代码实现)

信用评分模型是近年来兴起的一种为了保障银行和其他金融部门的金融安全而设立的一种关于人身金融权限的划定模型。该模型指根据客户的信用历史资料,利用一定的信用评分模型,得到不同等级的信用分数,根据客户的信用分数,来决定客户所可以持有的金额权限,从而保证还款等业务的安全性。而随着在现代社会和公司中,贷款,信用卡的作用日渐突出,信用评分模型的发展前景不可估量。信贷风险是指借款人因偿还贷款或履行合同承诺而破产而产生损失的可能性。传统上,它与贷款人无法偿还所欠利息和本金、影响现金流和增加装配成本所产生的风险有关。

qq_36130719的博客 365

Struts2权威指南总结3:Struts2基础

1,struts1的mvc实现: Struts1是世界上最古老的mvc框架,出现于2001年。由ActionServlet作为核心API。 Struts1使用ActionForm接受请求参数。   2,WebWork WebWork以ServletDispatcher为核心。使用ServletDispatcher处理用户的所有请求,它是整个WebWork框架的核心控制器。 WebWor

您已进入防沉迷系统... 1400

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Struts2基础

一、简介   struts2是一个基于MVC设计模式的web应用框架   它的本质相当于一个servlet,在MVC设计模式中,struts2作为控制器(Controller)来建立模型与视图的数据交互。   struts2以Web Work为核心,采用拦截器的机制来处理用户请求,这样的设计也使得业务逻辑控制器能够与servletAPI完全脱离开。      web框架特点:     ...

weixin_30784141的博客 108

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Struts2基础知识整理

Struts2是基于MVC设计模式的WEB框架,这个框架的的核心就是J2EE的过滤器Filter,通过Filter把所有请求转交给Struts2来处理 要使用Struts首先我们先要导入JAR包,同样的,我把完整的Struts分享给大家:                    链接:https://pan.baidu.com/s/1rQQAlusPkggK4SODJz2tNA 密码:6fi3 ...

weixin_42668719的博客 412

struts2基础

待整理

garage90的专栏 281

Struts2.x基础

【代码】Struts2.x基础。

bishe361的博客 189

Struts2开发基础

Struts2开发基础 struts2采用拦截器的机制来处理用户的请求,使得业务逻辑控制器能够与ServletAPI完全脱离开。 1.HelloWorld! 配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_9" version="2.4...

weixin_30838873的博客 84

Struts2基础详解

Struts2版本 登录struts的官网,然后我们就能看到如下的内容。选择相应的安装包进行下载 Struts2应用开发步骤在web.xml文件中定义核心Filter来拦截用户请求 在web.xmlwen中配置如下片段 <!--定义struts2的核心Filter--> <filter> <filter-name>str

Emily的博客 462

Struts2目录结构和基础JAR包介绍

Struts2的官方下载网址为http://struts.apache.org,在该网址中可以下载最新版本的 Struts2。 下载成功后,将压缩包进行解压,解压后的目录如图 1 所示。 图 1Struts2 的文件夹结构 下面针对图 1 中所示的目录进行简单介绍,具体如表 1 所示。 表 1 Struts2 的目录介绍 名称 作用 apps 用于存放官方提供的 Struts2 示例程序,这些程序可以作为学习者的参考资料。各示例均为 war 文件,可以通过 zip 方式进行...

段远山 618

Struts2基础标签

1、Struts2基础标签 1)输出 --value属性中写的是OGNL表达式 假设Action中有userName属性 2)循环 --value属性中写的是OGNL表达式, 该表达式访问的是Action中的集合属性。 3)控制 --test属性中写的是OGNL表达式。 2、

u012162642的专栏 522

Struts2基础学习总结

Struts2基础学习总结 Struts 2是在WebWork2基础发展而来的。 注意:struts 2和struts 1在代码风格上几乎不一样。 Struts 2 相比Struts 1的优点: 1、在软件设计上Struts 2 没有像Struts 1那样跟Servlet API 和 struts API 有着紧密的耦合。      Struts 2的应用可以不依赖于Se

LOADING 537
上一篇: 《Java Web开发教程——入门与提高篇(JSP+Servlet)》前言
下一篇: JDBC程序的常见错误及调试
老李-大连
博客等级 码龄20年 3206粉丝 308原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值