Web开发 | Struts2 - 03.国际化和异常处理机制

1.Java程序与Struts2的国际化

  程序国际化:程序可以根据机器所在的国家、语言环境,自动显示当前国家、语言的内容。

  国际化的本质:查找、替换。

国际化的步骤:
  1、为不同的国家、语言环境提供资源包。
    如果你的国际化语言资源包中有非西欧字符,要使用native2asciii命令处理该文件。
  2、在程序中输出国际化消息的key。

Struts2的国际化
  1、支持模块化加载。
  2、Struts2支持自动加载国际化资源。

  一、JSP页面的国际化:
    1、需要手动加载国际化消息
      使用<s:i18n…/>
    2、在页面使用<s:text…/>根据key来输出国际化消息
      如果是表单标签,直接使用key来指定国际化消息的key

  二、Action的国际化
    1、自动加载国际化消息。
      让国际化消息的baseName与Action的类名相同,而且放在同一个目录下。
    2、在Action类中调用getText()方法来加载国际化消息。

  三、包范围的国际化
    1、自动加载国际化消息。
      让国际化消息的baseName与package相同(不是与包名相同),而且放在同一个目录下。可以让该包下的所有Action共享同一个国际化资源文件。
    2、在Action类中调用getText()方法来加载国际化消息。

  四、全局国际化资源文件
    1、通过一个struts.custom.i18n.resources常量来加载国际化资源。
    2、全局国际化资源文件,即可被Action访问,也可以被JSP页面访问。

Action接口与ActionSupport实现类:
  ActionSupport实现了Action接口,而且增加了输入校验支持、国际化支持等功能。


Java的国际化案例

查看不同的国家、语言的代码

  /HelloWorld/src/LocaleTest.java
程序代码如下:

import java.util.Locale;

public class LocaleTest {
    public static void main(String[] args)
    {
        Locale[] locales = Locale.getAvailableLocales();
        for(Locale locale : locales)
        {
            //查看每种语言文字对应的代码
            System.out.println(locale.getDisplayLanguage()
                    + "-->" + locale.getLanguage());
            //查看每个国家对应的代码
            System.out.println(locale.getDisplayCountry()
                    + "-->" + locale.getCountry());
        }
    }
}

编写测试类

  /HelloWorld/src/HelloWorld.java
程序代码如下:

import java.util.Locale;
import java.util.ResourceBundle;

public class HelloWorld {
    public static void main(String[] args)
    {
        //获取程序所在的机器的语言、国家环境
        Locale locale = Locale.getDefault(Locale.Category.FORMAT);
        //告诉系统,要到bundle所加载的语言资源包,去查找hi对应的字符串
        ResourceBundle bundle = ResourceBundle.getBundle("zidingyi",locale);
        System.out.println(bundle.getString("hi"));
    }
}

同目录下新增语言资源文件

  /HelloWorld/src/zidingyi_en_US.properties
程序代码如下:

hi=HelloWorld!

  /HelloWorld/src/zidingyi_zh_CN.properties
程序代码如下:

hi=\u6B22\u8FCE\u4F60\uFF0C\u771F\u9AD8\u5174\uFF01

zidingyi_zh_CN

运行
(系统语言环境为“中文(简体,中国)”)
运行项目
设置系统语言环境并运行
(控制面板-区域和语言-格式-英语(美国))
运行项目


Struts2的JSP国际化案例

(基于Struts2空项目)

新建视图页面

  /JSPI18N/WebContent/WEB-INF/content/loginForm.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- name填写国际化消息的baseName -->
<s:i18n name="resource/loginForm">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><s:text name="loginTitle" /></title>
</head>
<body>
<!-- 
    1、更简单
    2、自动支持2列布局
    3、自动输出类型转换失败,输入校验失败的错误提示信息
-->
<s:form action="loginPro">
    <s:textfield name="name" key="name"/>
    <s:password name="pass" key="pass"/>
    <s:submit key="login"/>
</s:form>
</body>
</html>
</s:i18n>

src下新建resource目录再新建两个资源文件

  /JSPI18N/src/resource/loginForm_en_US.properties
程序代码如下:

loginTitle=Login Page!
name=Your Name
pass=Your PassWord
login=Log In

  /JSPI18N/src/resource/loginForm_zh_CN.properties
程序代码如下:

loginTitle=\u767B\u5F55\u9875\u9762
name=\u7528\u6237\u540D
pass=\u5BC6\u7801
login=\u767B\u5F55

运行项目
运行项目
切换语言环境
运行项目


Struts2的Action国际化案例

(基于JSPI18N项目)

新建Action

  继承ActionSupport类的LoginProAction.java
  /ActionI18N/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import com.opensymphony.xwork2.ActionSupport;

public class LoginProAction extends ActionSupport {
    private String name;
    private String pass;
    private String tip;
    private String login;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPass() {
        return pass;
    }
    public void setPass(String pass) {
        this.pass = pass;
    }
    public String getTip() {
        return tip;
    }
    public void setTip(String tip) {
        this.tip = tip;
    }


    public String getLogin() {
        return login;
    }
    public void setLogin(String login) {
        this.login = login;
    }
    @Override
    public String execute(){
         String succTip = getText("succTip");
         System.out.println(succTip);  
        if(name.equals("123")&&pass.equals("456")){
            //getText是ActionSupport的方法,专门用于加载国际化消息
            //getText的数组参数用于为国际化消息中的多个占位符传入参数值。
            setTip(getText("succTip",new String[]{name}));
            return SUCCESS;
        }
        return ERROR;
    }

}

同目录下新建资源文件

  /ActionI18N/src/Struts2/action/LoginProAction_en_US.properties
程序代码如下:

succTip=welcome,{0},Login Successful!

  /ActionI18N/src/Struts2/action/LoginProAction_zh_CN.properties
程序代码如下:

succTip=\u6B22\u8FCE\u4F60\uFF0C{0}\uFF0C\u767B\u9646\u6210\u529F\uFF01

程序代码

配置Action

  /ActionI18N/src/struts.xml
程序代码如下:

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

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">

<!-- START SNIPPET: xworkSample -->
<struts>
    <constant name="struts.devMode" value="true"></constant>
    <package name="default" namespace="/" extends="struts-default">
        <action name="loginPro" class="Struts2.action.LoginProAction">
            <result>/WEB-INF/content/welcome.jsp</result>
        </action>

        <action name="*">
            <result>/WEB-INF/content/{1}.jsp</result>
        </action>
    </package>
</struts>
<!-- END SNIPPET: xworkSample -->

新建视图页面

  /ActionI18N/WebContent/WEB-INF/content/welcome.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- name填写国际化消息的baseName -->
<s:i18n name="resource/welcome">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><s:text name="succ" /></title>
</head>
<body>
<h3><s:text name="succ" /></h3>
${tip}
</body>
</html>
</s:i18n>

src下新建resource目录再新建两个资源文件

  /ActionI18N/src/resource/welcome_en_US.properties
程序代码如下:

succ=Login successful!

  /ActionI18N/src/resource/welcome_zh_CN.properties
程序代码如下:

succ=\u767B\u9646\u6210\u529F

程序代码

  运行项目http://localhost:8080/ActionI18N/loginForm

运行项目
运行项目
运行项目
运行项目


全局国际化案例

(基于ActionI18N项目)

src下新建resource目录再新建两个资源文件
将原有的资源(包括Action的)分类放入新的对应的资源文件里面

  /GlobalI18N3/src/resource/mess_en_US.properties
程序代码如下:

loginTitle=Login Page!
name=Your Name
pass=Your PassWord
login=Log In

succ=Login successful!

succTip=welcome,{0},Login Successful!

  /GlobalI18N3/src/resource/mess_zh_CN.properties
程序代码如下:

loginTitle=\u767B\u5F55\u9875\u9762
name=\u7528\u6237\u540D
pass=\u5BC6\u7801
login=\u767B\u5F55

succ=\u767B\u9646\u6210\u529F

succTip=\u6B22\u8FCE\u4F60\uFF0C{0}\uFF0C\u767B\u9646\u6210\u529F\uFF01

删掉原有的资源文件
删掉原有的资源文件

在struts.xml中配置

  /GlobalI18N3/src/struts.xml
程序代码如下:

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

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">

<!-- START SNIPPET: xworkSample -->
<struts>
    <constant name="struts.devMode" value="true"></constant>
    <constant name="struts.custom.i18n.resources" value="resource/mess"></constant>
    <package name="default" namespace="/" extends="struts-default">
        <action name="loginPro" class="Struts2.action.LoginProAction">
            <result>/WEB-INF/content/welcome.jsp</result>
        </action>

        <action name="*">
            <result>/WEB-INF/content/{1}.jsp</result>
        </action>
    </package>
</struts>
<!-- END SNIPPET: xworkSample -->

视图页面中删掉<s:i18n>标签

  /GlobalI18N3/WebContent/WEB-INF/content/loginForm.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- name填写国际化消息的baseName -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><s:text name="loginTitle" /></title>
</head>
<body>
<!-- 
    1、更简单
    2、自动支持2列布局
    3、自动输出类型转换失败,输入校验失败的错误提示信息
-->
<s:form action="loginPro">
    <s:textfield name="name" key="name"/>
    <s:password name="pass" key="pass"/>
    <s:submit key="login"/>
</s:form>
</body>
</html>

  /GlobalI18N3/WebContent/WEB-INF/content/welcome.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- name填写国际化消息的baseName -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><s:text name="succ" /></title>
</head>
<body>
<h3><s:text name="succ" /></h3>
${tip}
</body>
</html>

  运行项目http://localhost:8080/GlobalI18N/loginForm

运行项目
运行项目
运行项目
运行项目


2.用户选择语言国家环境

  Struts2默认是根据浏览器的设置来选择语言、国家环境。
  Struts2还提供了机制,让用户来选择自己的语言、国家环境。根据request_locale来确定。

(基于GlobalI18N项目)
新建视图文件

  /CustomerI18N/WebContent/WEB-INF/content/selectLanguage.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:i18n name="resource/selectLanguage">
<!-- bean标签的作用就是根据类型创建一个实例,并为实例起个名字 -->
<s:bean var="zidingyi" name="Struts2.action.Locales"/>
<!-- 列出国有的程序所支持的语言 -->
<!-- select标签会自动生成一个下拉列表框
    每个key-value对会自动生成一个下拉列表框
<select>
    <option value="xx">aaa</option>
</select>
 -->
 <!-- 生成一个URL地址 -->
 <s:url var="curURL" />
 <s:form>
 <!-- 通过JavaScript设置当前用户选择的值发生改变时提交该表单 -->
 ${request_locale} 
     <s:select id="langSelect" list="#zidingyi.locales"
        listKey="value"
        listValue="key"
        key="selectLang"
        name="request_locale"
        value="request_locale"
        onchange="this.form.submit();"
     />
 </s:form>
 <script type="text/javascript">
    document.getElementById("langSelect").value="${param.request_locale}";
 </script>
 </s:i18n>

新建Action

  /CustomerI18N/src/Struts2/action/Locales.java
程序代码如下:

package Struts2.action;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class Locales {
    Map<String, Locale>locales;
    {
        locales = new HashMap();
        locales.put(Locale.CHINA.getDisplayLanguage(Locale.CHINA), Locale.CHINA);
        locales.put(Locale.US.getDisplayLanguage(Locale.US), Locale.US);
    }
    public Map<String, Locale> getLocales()
    {
        return locales;
    }
}

src下新建resource目录再新建两个资源文件

  /CustomerI18N/src/resource/selectLanguage_en_US.properties
程序代码如下:

selectLang=Please Choose Language

  /CustomerI18N/src/resource/selectLanguage_zh_CN.properties
程序代码如下:

selectLang=\u8BF7\u9009\u62E9\u8BED\u8A00

  运行项目http://localhost:8080/CustomerI18N/selectLanguage

运行项目
运行项目


3.异常机制和详细配置

Struts2的异常处理:
  传统的Web编程的异常模式

    try
    {
        业务代码
    }
    catch(XxxException xe)
    {
        forward("/a.jsp")
    }

对于Action的处理方法而言,处理结果可能出现如下情况:
  1、正常执行结束,会返回一个Sting类型的逻辑视图。对于String类型的逻辑视图,使用<result name="逻辑视图名">物理视图资源</result>
  2、遇到异常,返回一个异常对象。
    <exception-mapping exception="异常类" result="逻辑视图名" />

Struts2的异常配置的本质:为不同的异常类,命名一个逻辑视图名。

  局部异常映射:将<exception-mapping … />元素作为<action…/>元素的子元素配置。
  全局异常映射:将<exception-mapping … />元素作为<global-exception-mapping…/>元素的子元素配置。

  全局异常映射的result属性值通常不要使用局部结果。局部异常映射的result属性值既可以使用全局结果,也可以使用局部结果。

  Struts2设计的处理方法完全不需要处理任何异常,它可以声明抛出任意的异常。

  在异常处理页面上显示异常信息,可以使用Struts2如下标签来输出异常信息:
    <s:property value="exception"/>:输出异常对象本身。
    <s:property value="exception.getmessage"/>:输出异常堆栈信息。


异常处理案例
(基于Struts2空项目)

新增视图资源

  /exceptionHandler/WebContent/WEB-INF/content/loginForm.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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=utf-8">
<title>登录系统</title>
</head>
<body>
<s:form action="loginPro">
    <s:textfield name="name" label="用户名"/>
    <s:password name="pass" label="密码"/>
    <s:submit value="登录"/>
</s:form>
</body>
</html>

新增Action类

  /exceptionHandler/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import java.sql.SQLException;

import com.opensymphony.xwork2.ActionSupport;

public class LoginProAction extends ActionSupport 
{
    private String name;
    private String pass;
    private String tip;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPass() {
        return pass;
    }
    public void setPass(String pass) {
        this.pass = pass;
    }
    public String getTip() {
        return tip;
    }
    public void setTip(String tip) {
        this.tip = tip;
    }

    @Override
    public String execute() throws Exception
    {
        if(name.equalsIgnoreCase("sql"))
        {
            throw new SQLException("用户名不能为SQL字符串!");
        }
        if(name.length() > 10)
        {
            throw new IllegalArgumentException("用户名长度超了!");
        }
        if(name.equals("123")&&pass.equals("456"))
        {
            setTip("用户:" + name + "登录成功!");
            return SUCCESS;
        }else{
            return ERROR;
        }
    }
}

配置Action

  /exceptionHandler/src/struts.xml
程序代码如下:

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

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">

<!-- START SNIPPET: xworkSample -->
<struts>
    <constant name="struts.devMode" value="true"></constant>

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

        <global-results>
            <result name="null">/WEB-INF/content/error.jsp</result>
            <result name="unknow">/WEB-INF/content/error.jsp</result>
        </global-results>

        <!-- 全局的异常映射所谓异常映射的本职,就是为处理方法所抛出的异常类起个名字-->
        <global-exception-mappings>
            <exception-mapping result="null" exception="java.lang.NullPointerException"></exception-mapping>
            <exception-mapping result="unknow" exception="java.lang.Exception"></exception-mapping>
        </global-exception-mappings>

        <action name="loginPro" class="Struts2.action.LoginProAction">
            <exception-mapping result="sql" exception="java.sql.SQLException"/>
            <exception-mapping result="illegal" exception="java.lang.IllegalArgumentException"/>
            <result>/WEB-INF/content/welcome.jsp</result>
            <result name="error">/WEB-INF/content/fail.jsp</result>
            <result name="sql">/WEB-INF/content/sqlError.jsp</result>
            <result name="illegal">/WEB-INF/content/illegalError.jsp</result>
        </action>

        <action name="*">
            <result>/WEB-INF/content/{1}.jsp</result>
        </action>
    </package>
</struts>
<!-- END SNIPPET: xworkSample -->

新增视图资源

  /exceptionHandler/WebContent/WEB-INF/content/error.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!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=utf-8">
<title>通用异常的页面</title>
</head>
<body>
<h2>通用异常的页面</h2>
</body>
</html>

  /exceptionHandler/WebContent/WEB-INF/content/fail.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!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=utf-8">
<title>登录失败的页面</title>
</head>
<body>
<h2>登录失败的页面</h2>
</body>
</html>

  /exceptionHandler/WebContent/WEB-INF/content/illegalError.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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=utf-8">
<title>非法参数异常的页面</title>
</head>
<body>
<h2>非法参数异常的页面</h2>
异常信息:<s:property value="exception.getmessage"/>
</body>
</html>

  /exceptionHandler/WebContent/WEB-INF/content/sqlError.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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=utf-8">
<title>sql异常的页面</title>
</head>
<body>
<h2>sql参数异常的页面</h2>
<s:property value="exception"/>
</body>
</html>

  /exceptionHandler/WebContent/WEB-INF/content/welcome.jsp
程序代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!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=utf-8">
<title>登录系统</title>
</head>
<body>
${tip}
</body>
</html>

  运行项目http://localhost:8080/exceptionHandler/loginForm

运行项目
运行项目
运行项目
运行项目
运行项目
运行项目

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值