• Java框架之Struts2(五)


    本文主要介绍Struts2 文件上传、Struts2 多文件上传、文件下载、上传文件的过滤、输入校验、输入校验的流程。

    一、Struts2 文件上传

    步骤:

    1) 页面

    <form action="FileUpAction" method="post" enctype="multipart/form-data" >
          <input type="file" name="fileAAA" >
          <input type="submit" value="上传">
    </form>

    2)

    public class FileUpAction extends BaseAction{
                    private File fileAAA; //用来得到上传的文件,注意,它的名字必须和表单中的属性名相同
                    private String fileAAAContentType ; //得到文件的类型,名字必须这么叫 fileAAA + ContentType
                    private String fileAAAFileName; //得到文件名,必须这么叫 fileAAA+FileName
                     ..  一定不要忘了 get 和  set 方法
                    
                    public String uploadFile() throws IOException{
                        String realpath=ServletActionContext.getServletContext().getRealPath("/up_images");
                        System.out.println(realpath);
                        
                        File f=new File(realpath,fileAAAFileName); //  c:/tomcat/xxx/up_images/dog.jpg
                        FileUtils.copyFile(fileAAA,f); //FileUtils 是 org.apache.commons.io 包中的
                        
                        //msg="上传文件成功";
                        ActionContext ctx=ActionContext.getContext();
                        ctx.put("info", "文件上传成功");
                        ctx.put("fileAAAFileName", fileAAAFileName);
                        
                        return "success";
                    }
                }

    3)配置文件

    <package name="p_fileup" extends="struts-default" >
        <action name="fileUpAction" class="cat.action.FileUpAction" method="uploadFile">
              <result name="success">/file_up.jsp</result>
        </action>
    </package>

     关键点总:

    1) form 表单的 enctype 一定要写成 multipart/form-data

    2) Action 中,要定义三个变量,而且命名有规则

    3) 可以使用 FileUtils 这样的工具类,简化操作

    4) 上传文件的大小,默认最大2m 如果想设置

    <constant name="struts.multipart.maxSize" value="104857600"></constant>   //这个value 是按字节算的

    二、Struts2 多文件上传

    1) multi_fileup.jsp

    <form action="multiFileUpAction" method="post" enctype="multipart/form-data" >
                    <input type="file" name="fileAAA" >
                    <input type="file" name="fileAAA" >
                    <input type="file" name="fileAAA" >
                    <input type="submit" value="上传">
    </form>
        
    ${info }

    2)

    public class MultiFileUpAction  extends BaseAction{
                    private File [] fileAAA; //用来得到上传的文件,注意,它的名字必须和表单中的属性名相同
                    private String [] fileAAAContentType ; //得到文件的类型,名字必须这么叫 fileAAA + ContentType
                    private String [] fileAAAFileName; //得到文件名,必须这么叫 fileAAA+FileName
                      //要生成get set 方法
                    
                    public String multiFileUp() throws IOException{
                        String realpath=ServletActionContext.getServletContext().getRealPath("/up_images"); 
                        for(int i=0;i<fileAAA.length;i++){
                            File f=new File(realpath,fileAAAFileName[i]);
                            FileUtils.copyFile(fileAAA[i], f);    
                            
                        //System.out.println(fileAAAContentType[i]); //image/pjpeg
                        }
                        
                        ServletActionContext.getRequest().setAttribute("info", "多个文件上传成功");
                        
                        以下几种方式也可以传送提示信息
                    /*    msg="哈哈,文件上传成功";
                        request.setAttribute("msg", "上传成功");
                        ActionContext.getContext().put("msg", "文件上传成功");*/
                        
                        return "success";     
                    }
                    
                    ...

    三、文件下载

    1) 在 file_up.jsp中加上

    <a href="downloadAction?fileName=${fileAAAFileName }"> 下载</a>   // ${fileAAAFileName } 指的是文件名

    2) action

    public class DownloadAction {
                     private String fileName;
                     public String execute(){
                         return "success"; 
                     }
                
                     public InputStream getInputStream() throws FileNotFoundException{
                         String directory=ServletActionContext.getServletContext().getRealPath("/up_images");
                         String path=directory+"/"+fileName;
                         return new FileInputStream(path);
                     }
                     
                    public String getFileName() {
                        //处理一下下载的时候,中文的问题
                      fileName = new String(fileName.getBytes(),"iso8859-1");  //这里要try catch
                        return fileName;
                    }
                
                    public void setFileName(String fileName) {
                        this.fileName = fileName;
                    }
                }

    3)配置文件

    <action name="downloadAction" class="cat.action.DownloadAction" >
        <result name="success" type="stream" > 
            <param name="contentType">text/plain</param>  //指定下载文件的类型,默认是 text/plain
            <param name="inputName">inputSteam</param>  //默认值是  inputSteam
            <param name="bufferSize">2048</param> //缓冲区
            <param name="contentDisposition">
                   attachment;filename="${fileName}"  动态的得到文件名,并指定
            </param>
                    
        </result>
    </action>

    需要注意的问题:

    如果图片名含有中文,在页面显示将是不正常的,可以在 tomcat 的 server.xml加上

    URIEncoding="utf-8"  这样的配置 如下:

    <Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" URIEncoding="utf-8" />

    四、上传文件的过滤

    == 用Struts2 带的拦截器过滤

    Struts2提供了一个上传文件的拦截器,通过配置它可以实现文件过滤,Struts2 中的文件,上传过滤器是 FileUpload. 可以在Action 中配置该拦截器的引用。配置FileUpload 拦截器时,可以指定两个参数。

    -- alowTypes 指定允许上传的文件类型,多个之间用逗号分隔

    -- maxmumSize 允许文件大小,以字节为单位

    == 手工过滤

    如果要手动判断文件类型,则通过 xxxContentType 属性即可。如果要判断文件大小,则通过 File对象获取文件大小是否符合即可。

    五、输入校验

    在struts 中,有两种校验方式

    1) 手工方式

    2) 基于xml配置的方式

    === 1)  手工方式

    验证的代码 写在 action 中

    通过重写 validate() 或 validateXxx() 方法实现

    //例一  验证action中的所有方法 在Action 中加入
    public void validate(){
          if("".equals(userName)||userName==null){
          //addFieldError 是从 ActionSupport 继承来的
                this.addFieldError("userName", "账号不能为空");
          }
                    
          if("".equals(phone)||phone==null){
                this.addFieldError("phone", "电话不能为空");
                }
          else{
          if(!phone.matches("1[3587]\d{9}")){
                this.addFieldError("phone", "电话格式不对");
                }
          }
    }

    2)在配置文件中

    <action name="userAction_*" class="cat.action.UserAction" method="{1}">
                <result name="success">/success.jsp</result>
                <result name="input">/user.jsp</result>  //出错以后,会自动转到叫 input 的视图
    </action>

    说明 :上面的 validate 会验证所有的该Action 中的方法

    3)页面

    //要导入 标签库 
    <%@ taglib uri="/struts-tags" prefix="s" %>
    <s:fielderror/>  //用来显示出错信息
      
    <form action="userAction_update"  method="post" >
          <input type="text" name="userName">
          <input type="text" name="phone">
          <input type="submit" />
    </form>
    //例二 明确指定要验证哪个方法在action 中
    public void validateAdd(){
            if("".equals(userName)||userName==null){
            //addFieldError 是从 ActionSupport 继承来的
                 this.addFieldError("userName", "账号不能为空");
                 }
            }                
                    
            //这个方法,只验证update方法
    public void validateUpdate(){
           if("".equals(phone)||phone==null){
                 this.addFieldError("phone", "电话不能为空");
                 }
           else{
           if(!phone.matches("1[3587]\d{9}")){
                 this.addFieldError("phone", "电话格式不对");
                 }
           }
    }
    //其他部分不变,可以发现,访问哪个方法,哪个方法将会被校验

    六、输入校验的流程

    1) 类型转换器(如果我们不提供,它用的是系统内部的类型转换器)对请求参数进行类型转换,并把转换后的值传给Action 中的属性

    2) 如果在执行类型转换的时候发生异常,系统会将异常信息保存到 ActionContext , conversionError 拦截器会把异常信息封装到fieldErrors里

    3) 系统会通过反射技术,调用 action中的 validateXxx() 方法,Xxx是方法名,如果有错误信息,也往 fieldErrors里放

    4) 调用 action中的 validate() 方法,如果有错误信息,也往 fieldErrors里放

    5) 经过上面的四步,如果  fieldErrors 存在错误信息,即这个集合的size大于0,系统会自动的把请求转到一个叫 input 的视图上,

    注意: 类型转换器转换时发生的异常,也会放到  fieldErrors里

    &&错误信息的显示

    1.el表达式法:

    ${errors.errMsg[0]}、${errors["user.id"][0]}  

    对于上例,可以这样取

    ${errors.userName[0]}  //得到用户名不能为空
    
    ${errors.phone[0]}  //得到电话不能为空

    2.ognl表达式:

    <s:property value="errors.errMsg[0]"/>、[s:property value="errors['syscode.code_id'][0]"/>

    3.ognl表达式(数据requestk 中取):

    <s:property value="#request.errors.errMsg[0]"/>、[s:property value="#request.errors['syscode.code_id'][0]"/>

    如果 validate  和 validateXxx 这两个方法都存在,先调用  validateXxx,再调用 validate

    附: 关于类型转换器出现的异常信息,如何自定义

    1) 在src 下加一个 message.properties 文件,内容如下:

    invalid.fieldvalue.age = 年龄不能是数字

    2) 配置文件中,引入这个资源文件

    <constant name="struts.custom.i18n.resources" value="message" /> 
  • 相关阅读:
    FB联网无人机取得重大进展 实现首次成功着陆
    科学家开发新AI系统,可读取大脑信息并表达复杂思想
    BGP基本配置的方法
    ContentProvider-------------自定义的内容提供者 然后去访问
    actionView
    actionBar_Tab导航
    Broadcast总结 service
    简单带进度条的音乐播放器
    AIDL--------应用之间的通信接口
    绑定服务-----------binderService TimerTask的使用
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/8110198.html
Copyright © 2020-2023  润新知