专栏首页浩CodingJava EE实用教程笔记----(5)第五章 Struts 2应用进阶

Java EE实用教程笔记----(5)第五章 Struts 2应用进阶

今天开始第五章啦,本章主要内容:Struts 2拦截器、Struts 2文件操作、Struts 2国际化。

第一部分 Struts 2拦截器

5.1.1 拦 截 器 概 述

Struts 2框架绝大部分功能在其内部都是通过拦截器完成的,拦截器是Struts 2的核心所在。Struts 2框架内建了大量的拦截器,这些拦截器可以在struts-default.xml(位于Struts 2完整版\src\core\src\main\resources目录下)中查看。

Struts 2框架给出了这么多的拦截器,下面简要介绍它们的作用:

5.1.2 拦 截 器 配 置

拦截器的配置是在struts.xml中完成的,定义一个拦截器使用<interceptor…/>标签,其格式如下:

这种情况的应用非常广。有的时候,如果需要在配置拦截器时就为其传入拦截器参数,只要在<interceptor..>与</interceptor>之间配置<param…/>标签即可。其格式如下:

在struts.xml中可以配置多个拦截器,它们被包在<interceptors></interceptors>之间,如下面的配置:

如果要应用这些拦截器,就需要在<action>配置中引用它们,一个<action>需要应用多个拦截器,这样就不免要有多条引用语句(引用拦截器用标签<interceptorref.../>),所以Struts 2给出了拦截器栈的使用,一个拦截器栈中可以包含多个拦截器,配置拦截器栈的格式为:

其实,在Struts 2框架中也配置有很多内置拦截器栈,在Struts 2的struts-default.xml中可以发现有如下拦截器栈的配置。

在struts-default.xml文件的最后还有这样一句代码:

该句是用来配置默认拦截器栈的,Struts 2框架自动配置了默认拦截器栈,这样每次当用户请求经过Struts 2框架处理时都会先由“defaultStack”这个默认拦截器栈来处理

拦截器或拦截器栈配置完成后就可以在<action>中对其引用了,一个action引用拦截器或拦截器栈的格式如下:

在为Action配置拦截器的时候,要先显示的配置默认的拦截器栈,因为在Action中单独配置了拦截器了的话,全局配置的默认拦截器栈“defaultStack”会失效,这是因为局部优先级大于全局优先级。

5.1.3 自定义拦截器并做一个小项目

Struts 2框架还提供了AbstractInterceptor类,该类实现了Interceptor接口,并提供了init()方法和destroy()方法的空实现。在一般的拦截器实现中都会继承该类,因为一般实现的拦截器是不需要打开资源的,故无须实现这两个方法,继承该类会更简洁。该类的代码实现为:

1.创建Struts 2项目

建立项目,取项目名为“InterceptorTest”。加载Struts 2包及修改web.xml文件,配置Struts 2,操作同【实例2.1】的第1步、第2步,不再赘述。

2.自定义拦截器类

创建自定义拦截器类“MyInterceptor.java”,编写代码如下:

package org.interceptor;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor{

public String intercept(ActionInvocation arg0) throws Exception {

System.out.println("我在Action前执行---->");

String result=arg0.invoke();

System.out.println("我在Action后执行---->");

return result;

}

}

3.编写测试用Action

创建Action类“TestAction.java”,编写代码如下:

package org.action;

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport{

public String execute() throws Exception {

System.out.println("我在Action中执行---->");

return NONE; //不做任何跳转

}

}

4.配置拦截器

在struts.xml中配置Action及拦截器,代码如下:

<?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>

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

<interceptors>

<interceptor name="myInterceptor" class="org.interceptor.MyInterceptor"/>

</interceptors>

<action name="test" class="org.action.TestAction">

<interceptor-ref name="defaultStack"></interceptor-ref>

<interceptor-ref name="myInterceptor"></interceptor-ref>

</action>

</package>

</struts>

5.运行测试

完这些简单的工作后,部署项目并启动服务器,在浏览器中输入“http://localhost:8080/InterceptorTest/test.action”请求,再查看控制台,出现如图所示的界面:

5.1.4 拦截器应用实例2——阻止表单重复提交

1.创建Struts 2项目

建立项目,取项目名为“InterceptorTest”。加载Struts 2包及修改web.xml文件,配置Struts 2,操作同【实例2.1】的第1步、第2步,不再赘述。

2.创建登录页

修改index.jsp作为登录页面:

<%@ page language="java" pageEncoding="UTF-8"%>

<%@ taglib uri="/struts-tags" prefix="s"%>

<html>

<head>

<title>登录界面</title>

</head>

<body>

<s:form action="login" method="post">

<!-- 每次提交一个token值,Struts2框架会检测是否是同一次表单提交-->

<s:token></s:token>

<s:textfield name="username" label="用户名"></s:textfield>

<s:password name="password" label="密码"></s:password>

<s:submit value="提交"></s:submit>

</s:form>

</body>

</html>

3.编写Action

编写Action类LoginAction.java,代码如下:

4.配置拦截器

5.编写JSP

成功返回界面welcome.jsp,代码如下:

5.编写JSP

重复提交的提示错误界面wrong.jsp,代码如下:

6.运行测试

部署运行该项目,输入用户名和密码进入成功界面,如图所示:

此时,刷新页面,或单击浏览器的返回再次提交,就会被拦截器拦截,跳转到如图所示的错误界面。

第二部分 Struts 2文件操作

5.2.1 文件上传实例

1.创建Struts 2项目

用Struts 2的Common-FileUpload框架上传多个文件。

建立项目,取项目名为“StrutsUpload”。加载Struts 2包及修改web.xml文件,配置Struts 2,操作同【实例2.1】的第1、2步,不再赘述。

2.修改index.jsp

在创建项目的时候,勾选自动生成index.jsp文件,读者可以应用该文件,将其中内容替换为自己编写的代码,注意:form的enctype一定要改为:“multipart/form-data”,以二进制流的方式来处理表单数据,如下:

3.编写Action类

在src下建立包action,在该包下建立自定义Action类UploadAction。该类的实现代码为:

package action;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport{

private List<File> upload; //上传的文件内容,由于是多个,用List集合

private List<String> uploadFileName; //文件名

public String execute() throws Exception {

if(upload!=null){

for (int i = 0; i < upload.size(); i++) { //遍历,得到每个文件对它们进行读写操作

InputStream is=new FileInputStream(upload.get(i));

OutputStream os=

new FileOutputStream("d:\\upload\\"+getUploadFileName().get(i));

byte buffer[]=new byte[1024];

int count=0;

while((count=is.read(buffer))>0){

os.write(buffer,0,count);

}

os.close();

is.close();

}

}

return SUCCESS;

}

public List<File> getUpload() {

return upload;

}

public void setUpload(List<File> upload) {

this.upload = upload;

}

public List<String> getUploadFileName() {

return uploadFileName;

}

public void setUploadFileName(List<String> uploadFileName) {

this.uploadFileName = uploadFileName;

}

}

在struts.xml中配置该Action类,代码如下:

4.建立success.jsp

上传成功后,跳转到成功页面。代码如下:

5.部署运行

如图所示,然后单击【上传】按钮,成功后跳转到成功页面,这时可以打开D盘的upload文件夹查看上传的文件。

5.2.2 文件下载

如果是一个以西欧字符(英文名字)命名的文件,可以直接用一个超链接指向要下载的文件即可:

<a href="/image/pic.jpg">点击下载</a>

如果包含非西欧字符(如中文日文)等命名的文件,就不能用上述方法了,下面这个实例有解决方案:在页面实现一个超链接,指向一个Action请求,在Action类中进行处理在struts.xml对Action进行配置的result中用param配置参数,完成文件的下载,下面介绍这些参数:

1.创建Struts 2项目

【实例5.5】用Struts 2框架的功能完成文件下载。

建立项目,取项目名为“StrutsDownload”。加载Struts 2包及修改web.xml文件,配置Struts 2,操作同【实例2.1】的第1、2步,不再赘述。在项目WebRoot下建立一个image文件夹,其中放入一个文件“用例.rar”,用于本例下载演示之用。

2.修改index.jsp

3.编写Action类

package org.action;

import java.io.InputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class DownloadAction extends ActionSupport{

private String downloadFile; //需要下载的文件路径

//生成set方法,该值由配置文件传递过来

public void setDownloadFile(String downloadFile) {

this.downloadFile = downloadFile;

}

//根据上面给出的文件路径,生成它的输入流

public InputStream getTargetFile(){

return ServletActionContext.getServletContext().getResourceAsStream(downloadFile);

}

public String execute() throws Exception {

return SUCCESS;

}

}

4.配置struts.xml文件

文件下载最重要的工作就是在配置文件中进行配置,下面看其struts.xml文件:

<struts>

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

<action name="download" class="org.action.DownloadAction">

<!-- 传递参数,指定要下载的文件的路径 -->

<param name="downloadFile">/image/用例.rar</param>

<result name="success" type="stream">

<!-- 输入流名称,对应Action类中的getTargetFile()方法 -->

<param name="inputName">targetFile</param>

<!-- 设置下载文件的文件名 -->

<param name="contentDisposition">

filename="example.rar"

</param>

<!-- 指定下载文件时缓冲区的大小 -->

<param name="bufferSize">4096</param>

</result>

</action>

</package>

</struts>

5.部署运行

部署项目,启动Tomcat,在浏览器中输入“http://localhost:8080/StrutsDownload/”,出现如图所示的界面,单击其上“下载”链接,就会弹出【新建下载任务】对话框,单击【浏览】按钮选择存盘路径,最后单击【下载】按钮开始下载进程。

第三部分 Struts 2国际化

5.3.1 国际化原理

国际化:是指在不修改程序代码的情况下,能根据不同的语言及地区显示不同的界面,就是语言转换。

实现原理:当用户选择了不同的语言后,程序会加载相对应的已经准备好的国际化资源文件来对程序进行赋值,来改变Web界面,其关键是提供不同国家语言的资源文件。简而言之:就是前端界面文字显示使用变量,根据用户选择的语言对变量进行赋值。

1.命名规则

Struts 2的国际化资源文件都是“*.properties”文件,而且该文件需要放在项目的classses文件夹下。就命名规则而言,国际化资源文件必须命名为“基本名称_语言代码_国家代码.properties”,例如,中文的国际化资源文件应命名为:

而英文国际化资源文件则命名为:

2.内容格式

资源文件内容的格式为“key=value”,其中key可以根据程序员自己的喜好来命名,但一般都会命名为容易理解或记忆的名称,而value值则是该key对应的值,不同国家语言对应的该值是不同的。例如,英文对应:

中文则对应:

看到这里,读者可能有点迷惑,按常理来说,中文对应的应该是:

因为中文是非西欧字符,要对其进行转码。目前MyEclipse可以自动进行中文转码。

5.3.2 资源文件的访问方式

1.使用<s:text>标签

2.使用标签属性key

3.使用getText()方法

getText()应用范围比较广泛,可以在页面使用,也可以在Action类或校验配置文件中使用。对于上面两个方法的应用都可以用该方法来代替:

3.使用getText()方法

5.3.3 国际化应用实例

【实例5.6】利用Struts 2的il8n拦截器以及国际化功能,开发左图所示的界面,刚开始为中文页面,如果单击下面的“英文”链接,就会出现如右图所示的英文页面。单击“chinese”链接,又回到左图的中文页面。

1.创建Struts 2项目

建立项目,取项目名为“SelectLanguageLogin”。加载Struts 2包及修改web.xml文件,配置Struts 2,操作同【实例2.1】的第1步、第2步,不再赘述。

2.创建资源文件

(1)创建英文资源文件。

建在src目录下,文件名为message_en_US.properties,代码如下:

language = please select language

chinese = chinese

english = english

loginView = Login View

XH = XH

KL = KL

login = login

(2)创建中文资源文件。

在src下创建文件message_zh_CN.properties,在其编辑区Properties选项页,单击【Add】按钮,添加并编辑各属性对应的中文名称,如图所示。

language=\u8BF7\u9009\u62E9\u8BED\u8A00

chinese=\u4E2D\u6587

english=\u82F1\u6587

loginView=\u767B\u5F55\u754C\u9762

XH=\u5B66\u53F7

KL=\u53E3\u4EE4

login=\u767B\u5F55

4.编写Action

本例的目的是体现国际化的应用而非登录验证功能本身,故在Action中不进行任何处理,直接返回“SUCCESS”,Action类的代码如下:

5.自定义拦截器

采取配置拦截器的方法,在进入“login.action”之前先对其进行语言的处理,拦截器代码实现为:

package org.interceptor;

import java.util.Locale;

import java.util.Map;

import com.opensymphony.xwork2.*;

import com.opensymphony.xwork2.interceptor.*;

public class CheckInterceptor extends AbstractInterceptor {

public String intercept(ActionInvocation arg0) throws Exception {

// 获得Action上下文

ActionContext ctx = arg0.getInvocationContext();

// 获得Session

Map session = ctx.getSession();

//检查是否设置了Locale,如果未设定,则默认为简体中文

Locale currentLocale=(Locale)session.get("WW_TRANS_I18N_LOCALE");

if(currentLocale==null){

// 设置Locale实例

currentLocale = new Locale("zh", "CN");

session.put("WW_TRANS_I18N_LOCALE", currentLocale);

}

return arg0.invoke();

}

}

struts.xml文件中配置拦截器,配置代码如下:

最后演示效果如开头所示。

本章实例代码GitEE地址:

https://gitee.com/jahero/bookManage.git

下章我们就开始一个Struts框架的实例综合应用啦,加油,共勉↖(^ω^)↗。

本文分享自微信公众号 - 浩Coding(gh_c4a2e63d2ca7),作者:浩

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java EE实用教程笔记----(2)第二章 Struts 2基础

    好了,今天开始第二章,O(∩_∩)O哈哈~,今天这一章主要讲Struts 2的运行环境和原理,及工作流程,后面长长的文章就当是看API把,哈哈。

    浩Coding
  • Linux中常用的系统命令

    本期文章主要简单介绍Linux中常用的系统命令,包括:stat、who、whoami、hostname、uname、top、ps、du、df、ifconfig、...

    浩Coding
  • 【程序猿硬核科普】推荐一款十分好用的终端工具XShell及其使用教程

    本篇文章主要介绍一款十分好用的终端工具XShell及其使用教程,包括:使用XShell连接服务器、使用XShell服务器上传文件、XShell改变字体颜色以及解...

    浩Coding
  • Android 华为凹口屏适配小结

    Android8.0 以后【凹口屏】得到迅速发展,目前已有了挖孔屏/水滴屏/刘海屏等各式各样的屏幕,究其根本依旧是【凹口屏】,单华为一个品牌就涵盖了基本所有类...

    阿策
  • 进入不熟悉的领域,如何开展数据分析

    进入5月,同学们陆续入职新公司,很多人咨询如何在不熟悉的领域开展数据分析工作。这个问题很普遍,很多转行的同学在面试时就有被问到:“在不熟悉的领域做数据分析,你要...

    接地气的陈老师
  • 58龙哥教你“如何做系统性能优化”(纯干货)

    如何做系统性能优化 性能优化的目标是什么?不外乎两个: 时间性能:减小系统执行的时间 空间性能:减小系统占用的空间 一、代码优化 做代码优化前,先了解下硬件Ca...

    架构师之路
  • 死磕 java同步系列之CountDownLatch源码解析

    CountDownLatch,可以翻译为倒计时器,但是似乎不太准确,它的含义是允许一个或多个线程等待其它线程的操作执行完毕后再执行后续的操作。

    彤哥
  • 【DB笔试面试690】在Oracle中,什么是分布式事务处理?

    现代数据库系统往往伴随着复杂的结构和环境,其中,分布式数据库组成是一个重要方面。系统后台的数据库系统不再是由单个数据库构成,而是由多台独立数据库、甚至是多台异构...

    小麦苗DBA宝典
  • C++ OpenCV图像均值偏移滤波

    在图像分割的过程中,我们可以利用均值偏移算法的这个特性,实现彩色图像分割,均值漂移算法是一种通用的聚类算法,它的基本原理是:对于给定的一定数量样本,任选其中一个...

    Vaccae
  • Android Studio 2.2新特性:新布局、Firebase、OpenJDK以及Java 8

    尊重版权,未经授权不得转载 本文出自:贾鹏辉的技术博客(http://www.devio.org) 前几天,收到了Android Studio 2.2的...

    CrazyCodeBoy

扫码关注云+社区

领取腾讯云代金券