• struts2(三)之国际化、拦截器


    一、国际化

      1.1、国际化的定义

      软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。

      1.2、什么需要国际化

      程序:需要国际化

      数据:不需要国际化

      比如:软用户注册的表单,有用户名,密码这5个汉字,在zh_CN语言环境,显示的就是用户名和密码。但是在en_US语言环境,显示的就应该是username和password。这就是程序。

          我们在填写数据的时候,美女和123这样的数据是不需要的

      1.3、固定文本的国际化

          固定文本就是一些消息提示、错误提示、菜单、导航栏等等

        1.3.1、创建一个消息资源包    

        一个资源包由多个文件组成,这些文件名都有命名规范:主要文件名_语言代码_国家代码.properties。 语言代码:由iso规定的。国家代码:有iso规定的
        当文件只有主要文件名.properties时,表明它是默认资源包。浏览器会根据不同的语言环境找对应语言环境的资源包,当没有时,找默认的。
        每个资源包的内容都由相同的key和对应语言环境的value组成。

        比如:message_zh_CN.properties    message_en_US.properties  

        

        1.3.2、读取资源包的内容

        

        1.3.3、在jsp中使用国际化

        login.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <%
        Locale locale = request.getLocale();
        ResourceBundle bundle = ResourceBundle.getBundle("com.jxlg.resource.message", locale);
    %>
    <html>
      <head>
          <%=bundle.getString("jsp.login.title") %></br>
      </head>
      <body>
          <%=bundle.getString("jsp.login.username") %>:<input type="text" name="username" /></br>
          <%=bundle.getString("jsp.login.password") %>:<input type="password" name="password" /></br>
        <input type="submit" value="<%=bundle.getString("jsp.login.submit")%>:" />
    
    </body>
    </html>
    longin.jsp

      

     当浏览器的语言环境是用英文的时候                          当浏览器的语言环境是中文的时候

                  

      1.3.4、使用jstl中的fmt标签

      

    二、Struts中的国际化

      2.1、Struts使用国际化的要求   

        首先,我们要知道,在Struts2中,所有的消息提示都是基于国际化的。
        其次,要想在Struts2中使用国际化,动作类必须继承ActionSupport类。

      2.2、Struts使用国际化

        2.2.1、配置资源包

          A.配置全局资源包

          

          B.配置包范围的资源包

            资源包名称命名规范:package_语言代码_国家代码.properties(固定的)。以此种命名方式的资源包能被该包及其子包中的动作类访问。         

            优先级:高于全局消息资源包 

          C.局部消息资源包(只为动作类使用)    

        资源包名称命名规范:动作类名称_语言代码_国家代码.properties。以此种命名方式的资源包,只为动作类服务。
            优先级最高(就近原则)。

         

          Struts资源包的搜索顺序

          

      2.3、读取资源包的内容

        2.3.1、动作类中的读取方式(开发几乎不用)

        

      2.3.2、在页面中读取资源包内容

        直接访问jsp  

        

      结果    

       注意:当资源包没有中没有对应的的key值,则把key的内容显示到页面上

        通过动作类访问

        在struts.xml中的配置

        

        这是在访问demoi18n.jsp时结果是:

        

      2.4、自由指定读取资源包

        

    三、Struts中的拦截器(非常重要)  

      3.1、拦截器的重要性  

      Struts2中的很多功能都是由拦截器完成的。比如:servletConfig,staticParam,params,modelDriven等等。
      是AOP编程思想的一种应用形式。

      3.2、拦截器的执行时机

      

      3.3、自定义拦截器

        拦截器的类试图

        

      3.4、编写拦截器步骤

          1.编写一个类,继承AbstractInterceptor类或者实现Interceptor接口。重写intercept方法。

          

          2.配置拦截器:注意拦截器必须先声明后使用

          

          3.测试拦截器的执行顺序

          访问:

          

      3.5、多个拦截器的执行顺序

        struts.xml中的配置

        

        

        执行结果:

          

      3.6、intercept返回值

        返回的是逻辑结果视图

    四、拦截器的应用

      1.struts.xml中的配置

      

      2.Demo1Action.java动作类

      

      3.checkLoginInterceptor.java拦截器

      

      4.页面

      

      

      

      5.测试

      因为我们用来测试的,所以我们在动作类中直接就给user赋值了,相当于就是登录了。

      

      

      案例中的问题

        1.问题:由于我们写了自己的拦截器,默认的拦截器就不起作用了。

         解决办法:把默认的拦截器加到配置文件中

    <package name="p2" extends="struts-default">
            <interceptors>声明拦截器
                <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
            </interceptors>
            <global-results>全局结果视图
                <result name="input">/login.jsp</result>数据回显的结果视图
            </global-results>
            用户登录时,不需要检查登录的拦截器工作
            <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
                <result type="redirectAction">showMain</result>
            </action>
            前往主页的动作名称,需要检查登录的拦截器工作
            <action name="showMain" class="com.itheima.web.action.Demo2Action" >
                <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
                <result>/main.jsp</result>
            </action>
            前往另一个页面的动作名称,需要检查登录的拦截器工作
            <action name="showOther" class="com.itheima.web.action.Demo2Action" >
                <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
                <result>/otherpage.jsp</result>
            </action>
        </package>
    struts.xml

        2.问题:上面1中还是存在问题。当有多个拦截器时,需要改写的内容很多

          解决:抽取公共包,把全局配置放入公共包中

    <package name="p2" extends="struts-default">
            <interceptors>
                <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
                定义一个拦截器栈,把我们自定义的拦截器和默认的拦截器栈放到一起.
                <interceptor-stack name="myDefaultStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <global-results>
                <result name="input">/login.jsp</result>
            </global-results>
            <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
                <result type="redirectAction">showMain</result>
            </action>
            <action name="showMain" class="com.itheima.web.action.Demo2Action" >
                直接引入我们自己定义的拦截器栈,里面已经包含了默认的拦截器栈
                <interceptor-ref name="myDefaultStack"></interceptor-ref>
                <result>/main.jsp</result>
            </action>
            <action name="showOther" class="com.itheima.web.action.Demo2Action" >
                直接引入我们自己定义的拦截器栈,里面已经包含了默认的拦截器栈
                <interceptor-ref name="myDefaultStack"></interceptor-ref>
                <result>/otherpage.jsp</result>
            </action>
        </package>
    struts.xml

        3.问题:还要在每个动作方法中引入拦截器,能不能不用呢

         解决:我们在设置【开发模式】时,覆盖掉了一个default.properties中的常量,能不能把struts-default.xml中的默认拦截器栈的设置给覆盖掉呢?答案是可以的。

        

    <package name="p2" extends="struts-default">
            <interceptors>
                <interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
                <interceptor-stack name="myDefaultStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            覆盖了struts-default.xml中定义的默认拦截器栈。由myDefaultStack把defaultStack给替换了
            <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
            <global-results>
                <result name="input">/login.jsp</result>
            </global-results>
            <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
                <result type="redirectAction">showMain</result>
            </action>
            <action name="showMain" class="com.itheima.web.action.Demo2Action" >
                <result>/main.jsp</result>
            </action>
            <action name="showOther" class="com.itheima.web.action.Demo2Action" >
                <result>/otherpage.jsp</result>
            </action>
        </package>
    struts.xml

        4.问题:当使用默认的拦截器栈,这时候三个动作都会被检查登录拦截。

          解决:需要通过AbstractInterceptor类的子类入手,通过查看发现,该类还有一个子类是抽象的:           

            在AbstractInterceptor的子类中,还有一个抽象类MethodFilterInterceptor,它里面提供了两个属性。
            excludeMethods:哪些方法不需要拦截
            includeMethods:哪些方法需要拦截

          

        

        重新写拦截器类,这次我们继承MethodFilterInterceptor

    package com.itheima.web.interceptor;
    
    import javax.servlet.http.HttpSession;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
    /**
     * 检查登录的拦截器,最终版本
     * @author zhy
     *
     */
    public class CheckLoginInterceptor1 extends MethodFilterInterceptor {
    
        public String doIntercept(ActionInvocation invocation) throws Exception {
            //1.获取HttpSession
            HttpSession session = ServletActionContext.getRequest().getSession();
            //2.获取session域中的登录标记
            Object obj = session.getAttribute("user");
            //3.判断是否有登录标记
            if(obj == null){
                //用户没有登录
                return "input";
            }
            //4.用户登录了,放行
            String rtValue = invocation.invoke();
            return rtValue;
        }
    
    }
    CheckLoginInterceptor1

        并且在struts的配置文件中,配置需要拦截哪些方法,和需要放过哪些方法。

    <package name="p2" extends="struts-default">
            <interceptors>
                <interceptor name="checkLoginInterceptor1" class="com.itheima.web.interceptor.CheckLoginInterceptor1" />
                <interceptor-stack name="myDefaultStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="checkLoginInterceptor1">
                        给自定义拦截器注入参数,告知他哪些方法不需要拦截
                        <param name="excludeMethods">login</param>
                    </interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
            <global-results>
                <result name="input">/login.jsp</result>
            </global-results>
            <action name="login" class="com.itheima.web.action.Demo2Action" method="login">
                <result type="redirectAction">showMain</result>
            </action>
            <action name="showMain" class="com.itheima.web.action.Demo2Action" >
                <result>/main.jsp</result>
            </action>
            <action name="showOther" class="com.itheima.web.action.Demo2Action" >
                <result>/otherpage.jsp</result>
            </action>
        </package>
    struts.xml

        5.问题:我们在声明时配置了哪些方法需要拦截,哪些方法不需要拦截。但是在没有写动作类和动作方法之前,不确定方法名叫什么。

          解决:我们需要在使用拦截器的时候给它注入参数。告诉拦截器哪些需要拦截,哪些不需要

    package name="p2" extends="struts-default">
            <interceptors>
                <interceptor name="checkLoginInterceptor1" class="com.jxlg.web.interceptor.CheckLoginInterceptor1" />
                <interceptor-stack name="myDefaultStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="checkLoginInterceptor1"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
            <global-results>
                <result name="input">/login.jsp</result>
            </global-results>
            
            <action name="login" class="com.jxlg.web.action.Demo2Action" method="login">
                <interceptor-ref name="myDefaultStack">
                    <!-- 在引用自定义拦截器栈的时候,给指定的拦截器注入参数。方式就是:拦截器名称.属性名称 -->
                    <param name="checkLoginInterceptor1.excludeMethods">login</param>
                </interceptor-ref>
                <result type="redirectAction">showMain</result>
            </action>
            <action name="showMain" class="com.jxlg.web.action.Demo2Action" >
                <result>/main.jsp</result>
            </action>        
            <action name="showOther" class="com.jxlg.web.action.Demo2Action" >
                <result>/otherpage.jsp</result>
            </action>
        </package>
    struts.xml

      开发中就使用这种形式

      拦截器类视图

      

        

        

      

        

      

      

  • 相关阅读:
    尝试搭建springcloud项目(二)客户端client
    IDEA不识别yml
    尝试搭建springcloud项目(一)服务注册中心 Eureka
    curl与XPath
    curl发起网络请求
    Laravel Redis分布式锁的使用
    php 获取excel表格里面的数据
    php+redis实现简单秒杀抢购功能
    微信公众号模板消息推送
    永中,文档预览和转换的第三方平台
  • 原文地址:https://www.cnblogs.com/cxyzyh2017/p/6622827.html
Copyright © 2020-2023  润新知