Struts2--day03

作者: 键盘瞎 | 来源:发表于2017-02-05 20:56 被阅读90次

    非本人总结的笔记,抄点笔记复习复习。感谢传智博客和黑马程序猿


    记笔记啊记笔记

    Struts2国际化

    什么是国际化

    比如做一个软件,但是做软件,不仅中国人可以使用,其他国家的人也可以使用。根据操作系统的语言,自动识别显示的语言类型。
    现在使用国际化,完成的功能是:比如如果进行表单校验功能,校验失败提示错误信息,系统是英文则提示英文;中文则提示中文。

    国际互基本实现(配置全局国际化)

    创建一系列配置资源文件,命名规范:基本名称_小写的语言_大写的国家.properties
    比如:messaage_zh_CN.properties和message_en_US.properties
    本地系统是中文系统,读取到message_zh_CN.properties文件的内容

    Struts2实现国际化

    前提:创建一系列资源文件


    资源文件

    所有的资源文件key值要相同

    第一种:全局国际化(重点)

    配置全局国际化,在项目中的action、jsp页面中、校验文件中,都可以获取国际化内容

    实现的方式:通过Struts2的常量配置全局国际化

    struts.custom.i18n.resources常量配置的值是资源文件的基本名称。如果资源文件在src下,直接写基本名称;如果资源文件在包里面,加上包路径com/xxx/xxx

    <!--配置全局国际化-->
    <constant name="struts.custom.i18n.resources" value="message"></constant>
    
    1. 在action里面读取国际化资源文件内容

      //方法中的值 资源文件中key的名称
      String value = this.getText("namekey");
      
      资源文件内容
    2. 在jsp中读取国际化资源文件内容

      <!--读取全局国际化资源文件内容,使用struts2的标签读取-->
      <s:text name="namekey"></s:text>
      

      text标签,name属性值,资源文件中key的名称

    3. 在xml校验文件中读取

      <validators>
       <field name="username">
               <field-validator type="requiredstring">
                   <massage key="namekey"></massage>
               </field-validator>
           </field>
      </validators>
      

    第二种:action范围国际化

    只能在某一个action中获取到资源文件内容

    示例

    在action所在包里面创建资源文件,命名:action类名_小写语言_大写语言.properties

    获取示例

    String value = this.getText("actionkey");
    

    第三种:package范围国际化

    在包里面的所有的action可以获取到资源文件内容

    文件结构示例

    在包里面创建资源文件,命名 基本名称必须是package

    第四种:临时国际化(jsp获取资源文件内容)

    在jsp页面中,获取package.properties资源文件内容

    <!--struts2标签i18n标签-->
    <s:i18n name="cn/itcast/message/package">
        <s:text name="packagekey"></s:text>
    </s:i18n>
    

    Struts2的拦截器

    介绍

    使用Struts2操作发送请求,首先到过滤器里面,过滤器解析xml,acting匹配操作,在执行action之前,做执行一系列的拦截器,这些拦截器是Struts2帮实现的一些功能的封装,在Struts2里面默认执行的拦截器在struts-default.xml,273行配置默认值执行的拦截器

    Struts2的拦截器底层使用两部分原理

    第一个:aop思想(Aop面向方面编程(切面))

    比如有登录的功能,基本操作是输入表单数据,提交到Servlet中,判断用户名密码是否正确,最终如果正确到主页面,如果错误到登录页面,上面是登录到基本逻辑。

    Aop表示在基本功能之上添加一个额外的功能,实时添加功能,这个功能如果不添加,基本功能也可以运行。

    Aop面向方面编程

    第二种 责任链模式

    学过过滤器,有过滤链,一个请求可以有多个过滤器进行过滤,每个过滤器只有做放行才能到下一个过滤器

    责任链模式:在一条线有一组操作,执行这些操作,但是每个操作执行完成之后,做类似于放行操作,才能执行下一个方法。

    责任链模式执行过程

    查看Struts2关于拦截器源代码

    查看Struts2的过滤器

    StrutsPrepareAndExecuteFilter
    

    过滤器里面有init方法,加载配置文件

    doFilter方法,做过滤操作

    execute.executeAction(request, response, mapping);
    

    要执行action

    ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createAction(namespace, name, method, extraContext, true, false);
    

    生成action代理对象

    ActionContext previous = ActionContext.getContext();
    ActionContext.setContext(invocation.getInvocationContext());
    try{
      return invocation.invoke();
    }
    

    执行action之前,执行一系列的拦截器

    执行下一个操作

    return invocation.invoke();
    

    执行该过程描述:

    发送请求时候,首先到过滤器里面,在过滤器doFilter方法中执行action,首先生成action代理对象,执行,执行action之前,执行一系列默认的拦截器(把默认的拦截器拿过来),执行每一个拦截器之后做执行下一个操作,最终执行action逻辑

    拦截器构成

    类继承AbstractInterceptor,AbstractInterceptor类实现Interceptor接口

    AbstractInterceptor implements Interceptor
    

    在Interceptor接口里面有三个方法

    void init(); //初始化操作
    
    String intercept(ActionInvocation invocation) throw Exception;//写拦截器逻辑
    
    void destroy();//销毁操作
    

    自己写拦截器:

    1. 写类继承AbstractInterceptor类,重写类里面的方法Intercept方法,写拦截器逻辑
    2. 配置拦截器(注册拦截器)

    几个重要概念比较

    拦截器和过滤器比较

    过滤器:在到达目标资源之前进行的操作,过滤器可以过滤的内容有servlet、action、jsp、图片,过滤器理论上可以过滤任何的内容/*

    拦截器:在到达目标资源之前进行的操作,拦截器不能拦截jsp、图片。只能拦截action

    Action和Servlet比较

    Servlet:servlet默认在第一次访问时候创建,创建一次,servlet实例只有一个

    Action:action在访问时候创建,创建多次,每次访问action时候都会创建action实例

    自定义拦截器

    需求:登录拦截器

    1. 在页面中输入用户名和密码,提交数据到action中
    2. 在action中获取用户名和密码,判断用户名和密码是否正确
    3. 如果用户名和密码正确,到主页面中
      1. 登录成功后,把用户信息放到session里面,跳转到主页面
      2. 在主页面里面,写超链接,到另一个添加的action里面
    4. 如果用户名和密码不正确,到登录页面

    如果用户直接访问主页面,点击超链接到action中,如果没有登录,不能到action中页面,直接返回登录页面。

    实现的基本过程步骤:

    第一步 创建类,继承类

    public class MyInterceptor extends AbstracrInterceptor {
      //写拦截器逻辑
      @Override
      publicc String intercept(ActionInvocation invocation) throws Exception{
        //判断是否登录
        //判断session里面是否有数据
        ActionContext context = invocation.getInvocationContext();
        Object obj = context.getSession().get("user");
        if(obj != null) {
          //登录
          return invocation.invoke();
        } else {
          //不是登录
          return Action.LOGIN;
        }
      }
    }
    

    第二步 注册拦截器

    第一种方式:

    声明拦截器,在要拦截的action所在的包里面

    <!--声明拦截器-->
    <interceptors>
        <interceptor name="myloginintercept" class="cn.xxx.MyInterceptor"></interceptor>
    </interceptors>
    

    在action标签里面使用声明的拦截器

    <action name="adduser" class="com.xxx.AddUserAction">
        <result name="success">/login/add.jsp</result>
        <result name="login">/login/login.jsp</result>
        <!--如果使用自定义的拦截器,默认的拦截器失效,手动显示声明默认的拦截器-->
        <interceptor-ref name="defaultStack"></interceptor-ref>
        <!--使用自定义拦截器-->
        <interceptor-ref name="myloginintercept"></interceptor-ref>
    </action>
    

    第二种方式:

    声明拦截器栈

    <!--声明拦截器-->
    <interceptors>
        <interceptor name="myLoginIntercept" class="com.xxx.MyInterceptor"></interceptor>
        <intercepror-stack name="loginstack">
            <!--如果使用自定义的拦截器,默认的拦截器失效,手动显示声明默认的拦截器-->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <!--使用自定义拦截器-->
            <interceptor-ref name="myLoginIntercept"></interceptor-ref>
        </intercepror-stack>
    </interceptors>
    

    在action里面直接使用声明的栈

    <!--直接使用声明的栈-->
    <interceptor-ref name="loginstack"></interceptor-ref>
    

    Struts2实现文件上传

    Javaweb文件上传

    使用FileUpload组件,首先导入jar包

    步骤:

    1. 创建磁盘文件项工厂
    2. 创建核心上传类
    3. 解析request对象
    4. 解析之后返回List<FileItem>集合
    5. 遍历list集合,判断是普通输入项,还是文件上传项
    6. 如果是文件上传项,写上传代码

    Struts2里面在fileupload的基础之上做进一步封装

    要求:

    1. 提交方式post
    2. form标签里面属性enctype,属性值multipart/form-data
    3. 表单里面有文件上传项,type="file",必须有name属性

    实现过程

    第一步 声明几个变量

    ​ 第一个变量是上传文件private File文件上传项里面name的值

    ​ 第二个变量是上传文件的名称private String文件上传里面name属性值Filename

    ​ 第三个变量是上传文件的mime类型

    第一个变量是必须有的,但是第二个和第三个不是必须的

    private File upload;
    private String uploadFileName;
    

    第二步 生成声明变量的set和get方法

    public File getUpload() {
      return upload;
    }
    public void setUpload(File upload) {
      this.upload = upload;
    }
    public String getUploadFileName() {
      return uploadFileName;
    }
    public void setUploadFileName(String uploadFileName) {
      this.uploadFileName = uploadFileName;
    }
    

    第三步 在action的方法写上传的操作

    1. 获取到上传到服务器的文件夹路径
    2. 在服务器的文件夹中创建文件
    3. 把上传的文件内容复制到服务器上创建的文件中去
    //获取服务器上面文件夹的路径
    //使用servlet里面的ServletContext对象
    ServletContext context = ServletActionContext.getServletContext();
    String path = context.getRealPath("/img");
    //在服务器的文件夹里面创建文件
    File serverFile = new File(path+"/"+uploadFileName);
    //把上传的文件复制到服务器文件中
    FileUtils.copyFile(upload, serverFile);
    

    上传问题解决

    Struts2做上传,默认的上传的大小限制是2M,如果上传文件超过2M,返回提示信息,到页面中获取提示信息

    错误提示

    设置上传文件的大小,设置常量

    struts.multipart.maxSize=2097152 
    

    默认上传文件总大小是2M,常量的值是字节的单位

    Struts2实现多文件上传

    实现步骤

    第一步

    满足上传的三个要求,但是上传多个文件,在表单里面写多个文件上传项,多个文件上传项里面都有name属性,name属性值必须一样

    选择文件1:<input type="file" name="uploadimg"/><br>
    选择文件2:<input type="file" name="uploadimg"/><br>
    选择文件3:<input type="file" name="uploadimg"/><br>
    <input type="submit" value="上传"/>
    

    第二步

    声明几个变量,因为有多个值,使用数组形式声明

    private File[] uploadimg;
    private String[] uploadimgFileName;
    

    第三步 生成set和get方法

    public File[] getUploadimg() {
      return uploadimg;
    }
    public void setUpload(File[] uploadimg) {
      this.uploadimg = uploadimg;
    }
    public String[] getUploadimgFileName() {
      return uploadimgFileName;
    }
    public void setUploadimgFileName(String[] uploadimgFileName) {
      this.uploadimgFileName = uploadimgFileName;
    }
    

    第三步 在action方法中实现上传的操作

    变量数组,得到每一个文件的信息,一个一个的上传到服务器中

    //遍历得到每一个文件内容,一个个上传到服务器中
    for(int i = 0; i < uploadimgFileName; i++) {
      File uploadFile = uploadimg[i];
      String filename = uploadimgFileName[i];
      //实现上传
      String path = ServletActionContext.getServletContext().gerRealPath("/img");
      File serverFile = new File(path+"/"+filename);
      FileUtils.copyFile(uploadFile, serverFile);
    } 
    

    Struts2实现文件下载

    Javaweb实现文件下载

    第一步:获取服务器上的文件

    第二步:把文件通过流的方式写到浏览器中

    设置头 Content-Disposition,无论什么格式都是下载,而不是直接打开

    实现过程

    首先 在配置文件中配置下载的信息

    <package name="downloaddemo" extends="struts-default" namespace="/">
        <action name="down" class="com.xx.DownloadAction">
            <result name="success" type="stream">
                <param name="contentDisposition">attachment;filename=${filename}</param>
                <param name="inputStream">${inputStream}</param>
            </result>
        </action>
    </package>
    

    配置contentDisposition和inputStream

    这两个值通过action传递过来

    第二步 在action提供这个值的get方法

    //提供fileName的get方法
    String filename = "2.jpg";
    public String getFileName() {
      return filename;
    }
    public InputStream getInputStream() throws FileNotFoundException() {
      String path = ServlerActionContext.getServletContext().getRealPath("/img/"+filename);
      InputStream in = new FileInputStream(path);
      return in;
    }
    

    Struts下载中文名称文件乱码

    不同的浏览器有不同的编码,ie采用url编码,火狐采用base64编码

    首先,区分不同的浏览器

    Request对象,有方法getHeader(),使用头获取浏览器类型,头信息 User-Agent

    Request.getHeader(“User-Agent”);

    判断不同的浏览器,做不同编码

    如果是火狐,使用base64编码

    如果是ie及其他浏览器,使用url编码

    相关文章

      网友评论

        本文标题:Struts2--day03

        本文链接:https://www.haomeiwen.com/subject/fiftittx.html