• Struts2 文件上传,下载,删除


    本文介绍了:
    1.基于表单的文件上传
    2.Struts 2 的文件下载
    3.Struts2.文件上传
    4.使用FileInputStream FileOutputStream文件流来上传
    5.使用FileUtil上传
    6.使用IOUtil上传
    7.使用IOUtil上传
    8.使用数组上传多个文件
    9.使用List上传多个文件

    ----1.基于表单的文件上传-----

    fileupload.jsp

        <body>  
            <form action="showFile.jsp" name="myForm" method="post" enctype="multipart/form-data">  
                选择上传的文件   
                <input type="file" name="myfile"><br/><br/>  
                <input type="submit" name="mySubmit" value="上传"/>    
            </form>  
         </body>  

    showFile.jsp

        <body>  
             上传的文件的内容如下:   
             <%   
             InputStream is=request.getInputStream();   
             InputStreamReader isr=new InputStreamReader(is);   
             BufferedReader br=new BufferedReader(isr);   
             String content=null;   
             while((content=br.readLine())!=null){   
                 out.print(content+"<br/>");   
             }   
             %>  
          </body>  

    ----2.手动上传-----

    1. 通过二进制刘获取上传文件的内容,并将上传的文件内容保存到服务器的某个目录,这样就实现了文件上传。由于这个处理过程完全依赖与开发自己处理二进制流,所以也称为“手动上传”。   
    2. 从上面的第一个例子可以看到,使用二进制流获取的上传文件的内容与实际文件的内容有还是有一定的区别,包含了很多实际文本中没有的字符。所以需要对获取的内容进行解析,去掉额外的字符。

    ----3 Struts2.文件上传----

    1. Struts2中使用Common-fileUpload文件上传框架,需要在web应用中增加两个Jar 文件, 即 commons-fileupload.jar. commons-io.jar   
    2. 需要使用fileUpload拦截器:具体的说明在 struts2-core-2.3.4.jar org.apache.struts2.interceptorFileUploadInterceptor.class 里面    
    3. 下面来看看一点源代码 
        public class FileUploadInterceptor extends AbstractInterceptor {   
          
            private static final long serialVersionUID = -4764627478894962478L;   
          
            protected static final Logger LOG = LoggerFactory.getLogger(FileUploadInterceptor.class);   
            private static final String DEFAULT_MESSAGE = "no.message.found";   
          
            protected boolean useActionMessageBundle;   
          
            protected Long maximumSize;   
            protected Set<String> allowedTypesSet = Collections.emptySet();   
            protected Set<String> allowedExtensionsSet = Collections.emptySet();   
          
            private PatternMatcher matcher;   
          
         @Inject  
            public void setMatcher(PatternMatcher matcher) {   
                this.matcher = matcher;   
            }   
          
            public void setUseActionMessageBundle(String value) {   
                this.useActionMessageBundle = Boolean.valueOf(value);   
            }   
          
            //这就是struts.xml 中param为什么要配置为 allowedExtensions   
            public void setAllowedExtensions(String allowedExtensions) {   
                allowedExtensionsSet = TextParseUtil.commaDelimitedStringToSet(allowedExtensions);   
            }   
            //这就是struts.xml 中param为什么要配置为 allowedTypes 而不是 上面的allowedTypesSet    
            public void setAllowedTypes(String allowedTypes) {   
                allowedTypesSet = TextParseUtil.commaDelimitedStringToSet(allowedTypes);   
            }   
          
            public void setMaximumSize(Long maximumSize) {   
                this.maximumSize = maximumSize;   
            }   
        }  
    官员文件初始值大小 上面的类中的说明   
    <li>maximumSize (optional) - the maximum size (in bytes) that the interceptor will allow a file reference to be set   
     * on the action. Note, this is <b>not</b> related to the various properties found in struts.properties.   
     * Default to approximately 2MB.</li>  
    具体说的是这个值在struts.properties 中有设置。 下面就来看 里面的设置   
      
    ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data   
      
    文件上传解析器     
    # struts.multipart.parser=cos  
    # struts.multipart.parser=pell  
    #默认 使用jakata框架上传文件   
    struts.multipart.parser=jakarta  
      
    #上传时候 默认的临时文件目录     
    # uses javax.servlet.context.tempdir by default   
    struts.multipart.saveDir=   
      
    #上传时候默认的大小   
    struts.multipart.maxSize=2097152

    案例:使用FileInputStream FileOutputStream文件流来上传

    action.java

        package com.sh.action;   
          
        import java.io.File;   
        import java.io.FileInputStream;   
        import java.io.FileOutputStream;   
          
        import org.apache.struts2.ServletActionContext;   
          
        import com.opensymphony.xwork2.ActionSupport;   
          
        public class MyUpAction extends ActionSupport {   
               
            private File upload; //上传的文件   
            private String uploadContentType; //文件的类型   
            private String uploadFileName; //文件名称   
            private String savePath; //文件上传的路径   
               
        //注意这里的保存路径   
            public String getSavePath() {   
                return ServletActionContext.getRequest().getRealPath(savePath);   
            }   
            public void setSavePath(String savePath) {   
                this.savePath = savePath;   
            }   
            @Override  
            public String execute() throws Exception {   
                System.out.println("type:"+this.uploadContentType);   
                String fileName=getSavePath()+"\"+getUploadFileName();   
                FileOutputStream fos=new FileOutputStream(fileName);   
                FileInputStream fis=new FileInputStream(getUpload());   
                byte[] b=new byte[1024];   
                int len=0;   
                while ((len=fis.read(b))>0) {   
                    fos.write(b,0,len);   
                }   
                fos.flush();   
                fos.close();   
                fis.close();   
                return SUCCESS;   
            }   
        //get set   
        }  

    struts.xml

        <?xml version="1.0" encoding="UTF-8" ?>  
        <!DOCTYPE struts PUBLIC   
            "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"   
            "http://struts.apache.org/dtds/struts-2.3.dtd">  
          
        <struts>    
            <constant name="struts.i18n.encoding" value="utf-8"/>  
            <constant name="struts.devMode" value="true"/>     
            <constant name="struts.convention.classes.reload" value="true" />    
               
            <constant name="struts.multipart.saveDir" value="f:/tmp"/>  
            <package name="/user" extends="struts-default">  
                <action name="up" class="com.sh.action.MyUpAction">  
                    <result name="input">/up.jsp</result>  
                    <result name="success">/success.jsp</result>  
                    <!-- 在web-root目录下新建的一个 upload目录 用于保存上传的文件 -->  
                    <param name="savePath">/upload</param>  
                    <interceptor-ref name="fileUpload">  
                        <!--采用设置文件的类型 来限制上传文件的类型-->  
                        <param name="allowedTypes">text/plain</param>  
                        <!--采用设置文件的后缀来限制上传文件的类型 -->  
                        <param name="allowedExtensions">png,txt</param>  
                        <!--设置文件的大小 默认为 2M [单位:byte] -->  
                        <param name="maximumSize">1024000</param>  
                    </interceptor-ref>               
                               
                    <interceptor-ref name="defaultStack"/>  
                </action>  
            </package>  
        </struts>  

    up.jsp

        <body>  
          <h2>Struts2 上传文件</h2>  
           <s:fielderror/>  
          <s:form action="up" method="post" name="upform" id="form1" enctype="multipart/form-data" theme="simple">  
                选择文件:   
               <s:file name="upload" cssStyle="300px;"/>  
               <s:submit value="确定"/>  
          </s:form>         
        </body>  

    success.jsp

        <body>  
          <b>上传成功!</b>  
          <s:property value="uploadFileName"/><br/>  
          [img]<s:property value="'upload/'+uploadFileName"/>[/img]   
        </body>  

    案例:使用FileUtil上传

    action.java

        package com.sh.action;   
          
        import java.io.File;   
        import java.io.IOException;   
        import java.text.DateFormat;   
        import java.text.SimpleDateFormat;   
        import java.util.Date;   
        import java.util.Random;   
        import java.util.UUID;   
          
        import org.apache.commons.io.FileUtils;   
        import org.apache.struts2.ServletActionContext;   
          
        import com.opensymphony.xwork2.ActionContext;   
        import com.opensymphony.xwork2.ActionSupport;   
          
        public class FileUtilUpload extends ActionSupport {   
            private File image; //文件   
            private String imageFileName; //文件名   
            private String imageContentType;//文件类型   
            public String execute(){   
                try {   
                    if(image!=null){   
                        //文件保存的父目录   
                        String realPath=ServletActionContext.getServletContext()   
                        .getRealPath("/image");   
                        //要保存的新的文件名称   
                        String targetFileName=generateFileName(imageFileName);   
                        //利用父子目录穿件文件目录   
                        File savefile=new File(new File(realPath),targetFileName);   
                        if(!savefile.getParentFile().exists()){   
                            savefile.getParentFile().mkdirs();   
                        }   
                        FileUtils.copyFile(image, savefile);   
                        ActionContext.getContext().put("message", "上传成功!");   
                        ActionContext.getContext().put("filePath", targetFileName);   
                    }   
                } catch (IOException e) {   
                    // TODO Auto-generated catch block   
                    e.printStackTrace();   
                }   
                return "success";   
            }   
               
            /**  
             * new文件名= 时间 + 随机数  
             * @param fileName: old文件名  
             * @return new文件名  
             */  
            private String generateFileName(String fileName) {   
                //时间   
                DateFormat df = new SimpleDateFormat("yyMMddHHmmss");      
                String formatDate = df.format(new Date());   
                //随机数   
                int random = new Random().nextInt(10000);    
                //文件后缀   
                int position = fileName.lastIndexOf(".");      
                String extension = fileName.substring(position);      
                return formatDate + random + extension;      
            }   
        //get set   
          
        }  

    struts.xml

        <action name="fileUtilUpload" class="com.sh.action.FileUtilUpload">  
            <result name="input">/fileutilupload.jsp</result>  
            <result name="success">/fuuSuccess.jsp</result>  
        </action>  

    fileutilupload.jsp

        <form action="${pageContext.request.contextPath }/fileUtilUpload.action"    
           enctype="multipart/form-data" method="post">  
            文件:<input type="file" name="image"/>  
            <input type="submit" value="上传"/>  
           </form>  

    fuuSuccess.jsp

        <body>  
            <b>${message}</b>  
                ${imageFileName}<br/>  
            <img src="upload/${filePath}"/>  
          </body>  

    案例:使用IOUtil上传

    action.java

        package com.sh.action;   
          
        import java.io.File;   
        import java.io.FileInputStream;   
        import java.io.FileOutputStream;   
        import java.text.DateFormat;   
        import java.text.SimpleDateFormat;   
        import java.util.Date;   
        import java.util.UUID;   
          
        import org.apache.commons.io.IOUtils;   
        import org.apache.struts2.ServletActionContext;   
          
        import com.opensymphony.xwork2.ActionContext;   
        import com.opensymphony.xwork2.ActionSupport;   
          
        public class IOUtilUpload extends ActionSupport {   
          
            private File image; //文件   
            private String imageFileName; //文件名   
            private String imageContentType;//文件类型   
            public String execute(){   
                try {     
                   if(image!=null){   
                        //文件保存的父目录   
                        String realPath=ServletActionContext.getServletContext()   
                        .getRealPath("/image");   
                        //要保存的新的文件名称   
                        String targetFileName=generateFileName(imageFileName);   
                        //利用父子目录穿件文件目录   
                        File savefile=new File(new File(realPath),targetFileName);   
                        if(!savefile.getParentFile().exists()){   
                            savefile.getParentFile().mkdirs();   
                        }   
                        FileOutputStream fos=new FileOutputStream(savefile);   
                        FileInputStream fis=new FileInputStream(image);   
                           
                        //如果复制文件的时候 出错了返回 值就是 -1 所以 初始化为 -2   
                        Long result=-2L;   //大文件的上传   
                        int  smresult=-2; //小文件的上传   
                           
                        //如果文件大于 2GB   
                        if(image.length()>1024*2*1024){   
                            result=IOUtils.copyLarge(fis, fos);   
                        }else{   
                            smresult=IOUtils.copy(fis, fos);    
                        }   
                        if(result >-1 || smresult>-1){   
                            ActionContext.getContext().put("message", "上传成功!");   
                        }   
                        ActionContext.getContext().put("filePath", targetFileName);   
                   }   
                } catch (Exception e) {     
                    e.printStackTrace();     
                }     
                return SUCCESS;     
            }   
               
            /**  
             * new文件名= 时间 + 全球唯一编号  
             * @param fileName old文件名  
             * @return new文件名  
             */  
            private String generateFileName(String fileName) {   
                //时间   
                DateFormat df = new SimpleDateFormat("yy_MM_dd_HH_mm_ss");      
                String formatDate = df.format(new Date());   
                //全球唯一编号   
                String uuid=UUID.randomUUID().toString();   
                int position = fileName.lastIndexOf(".");      
                String extension = fileName.substring(position);      
                return formatDate + uuid + extension;      
            }   
        //get set   
        }  

    struts.xml

        <action name="iOUtilUpload" class="com.sh.action.IOUtilUpload">  
                    <result name="input">/ioutilupload.jsp</result>  
                    <result name="success">/iuuSuccess.jsp</result>  
        </action>  

    ioutilupload.jsp

    <form action="${pageContext.request.contextPath }/iOUtilUpload.action"    
        enctype="multipart/form-data" method="post">  
            文件:<input type="file" name="image"/>  
            <input type="submit" value="上传"/>  
    </form> 

    iuuSuccess.jsp

        <body>  
            <b>${message}</b>  
                ${imageFileName}<br/>  
            <img src="image/${filePath}"/>  
        </body>  

    案例:删除服务器上的文件

        /**  
             * 从服务器上 删除文件  
             * @param fileName 文件名  
             * @return true: 从服务器上删除成功   false:否则失败  
             */  
            public boolean delFile(String fileName){   
                File file=new File(fileName);   
                if(file.exists()){   
                    return file.delete();   
                }   
                return false;   
            }  

    案例:使用数组上传多个文件

    action.java

        package com.sh.action;   
          
        import java.io.File;   
        import java.io.FileInputStream;   
        import java.io.FileOutputStream;   
        import java.util.Random;   
          
        import org.apache.struts2.ServletActionContext;   
          
        import com.opensymphony.xwork2.ActionContext;   
        import com.opensymphony.xwork2.ActionSupport;   
          
        /**  
         * @author Administrator  
         *  
         */  
        public class ArrayUpload extends ActionSupport {   
          
            private File[] image;   
            private String[] imageContentType;   
            private String[] imageFileName;   
            private String path;   
               
            public String getPath() {   
                return ServletActionContext.getRequest().getRealPath(path);   
            }   
          
            public void setPath(String path) {   
                this.path = path;   
            }   
          
            @Override  
            public String execute() throws Exception {   
              for(int i=0;i<image.length;i++){   
                  imageFileName[i]=getFileName(imageFileName[i]);   
                  String targetFileName=getPath()+"\"+imageFileName[i];   
                  FileOutputStream fos=new FileOutputStream(targetFileName);   
                  FileInputStream fis=new FileInputStream(image[i]);   
                  byte[] b=new byte[1024];   
                  int len=0;   
                  while ((len=fis.read(b))>0) {   
                    fos.write(b, 0, len);   
                }   
              }   
              return SUCCESS;   
            }   
            private String getFileName(String fileName){   
                int position=fileName.lastIndexOf(".");   
                String extension=fileName.substring(position);   
                int radom=new Random().nextInt(1000);   
                return ""+System.currentTimeMillis()+radom+extension;   
            }   
        //get set   
        }  

    struts.xml

        <action name="arrayUpload" class="com.sh.action.ArrayUpload">  
                <interceptor-ref name="fileUpload">  
                    <param name="allowedTypes">  
                        image/x-png,image/gif,image/bmp,image/jpeg   
                    </param>  
                    <param name="maximumSize">10240000</param>  
                </interceptor-ref>  
                <interceptor-ref name="defaultStack"/>  
                <param name="path">/image</param>  
                <result name="success">/arraySuccess.jsp</result>  
                <result name="input">/arrayupload.jsp</result>  
            </action>  

    arrayUpload.jsp

        <body>  
           ===========多文件上传=================   
            <form action="${pageContext.request.contextPath }/arrayUpload.action"    
           enctype="multipart/form-data" method="post">  
            文件1:<input type="file" name="image"/><br/>  
            文件2:<input type="file" name="image"/><br/>  
            文件3:<input type="file" name="image"/>  
            <input type="submit" value="上传"/>  
           </form>  
         </body>  

    arraySuccess.jsp

        <body>  
            <b>使用数组上传成功s:iterator</b>  
            <s:iterator value="imageFileName" status="st"><s:property value="#st.getIndex()+1"/>个图片:<br/>  
                [img]image/<s:property value="imageFileName[#st.getIndex()][/img]"/>  
            </s:iterator>  
             <br/><b>使用数组上传成功c:foreach</b>  
             <c:forEach var="fn" items="${imageFileName}" varStatus="st">  
                第${st.index+1}个图片:<br/>  
                <img src="image/${fn}"/>  
             </c:forEach>  
          </body>  

    案例:使用List上传多个文件

    action.java

        package com.sh.action;   
          
        import java.io.File;   
        import java.io.FileInputStream;   
        import java.io.FileOutputStream;   
        import java.util.List;   
        import java.util.Random;   
          
        import javax.servlet.Servlet;   
          
        import org.apache.struts2.ServletActionContext;   
          
        import com.opensymphony.xwork2.ActionSupport;   
          
        public class ListUpload extends ActionSupport {   
        private List<File> doc;   
        private List<String> docContentType;   
        private List<String> docFileName;   
        private String path;   
        @Override  
        public String execute() throws Exception {   
            for(int i=0;i<doc.size();i++){   
                docFileName.set(i, getFileName(docFileName.get(i)));   
                FileOutputStream fos=new FileOutputStream(getPath()+"\"+docFileName.get(i));   
                File file=doc.get(i);   
                FileInputStream fis=new FileInputStream(file);   
                byte [] b=new byte[1024];   
                int length=0;   
                while((length=fis.read(b))>0){   
                    fos.write(b,0,length);   
                }   
            }   
            return SUCCESS;   
        }   
          
          
        public String getFileName(String fileName){   
            int position=fileName.lastIndexOf(".");   
            String extension=fileName.substring(position);   
            int radom=new Random().nextInt(1000);   
            return ""+System.currentTimeMillis()+radom+extension;   
        }   
        public String getPath() {   
            return ServletActionContext.getRequest().getRealPath(path);   
        }  

    strust.xml

        <action name="listUpload" class="com.sh.action.ListUpload">  
                    <interceptor-ref name="fileUpload">  
                        <param name="allowedTypes">  
                            image/x-png,image/gif,image/bmp,image/jpeg   
                        </param>  
                        <param name="maximumSize">  
                            10240000   
                        </param>  
                    </interceptor-ref>  
                    <interceptor-ref name="defaultStack"/>  
                    <param name="path">/image</param>  
                    <result name="success">/listSuccess.jsp</result>  
                    <result name="input">/listupload.jsp</result>  
                </action>  

    listUpload.jsp

        <body>  
            ===========List 多文件上传=================   
             <form action="${pageContext.request.contextPath }/listUpload.action"    
            enctype="multipart/form-data" method="post">  
                文件1:<input type="file" name="doc"/><br/>  
                文件2:<input type="file" name="doc"/><br/>  
                文件3:<input type="file" name="doc"/>  
                <input type="submit" value="上传"/>  
            </form>  
              
             <s:fielderror/>  
            <s:form action="listUpload" enctype="multipart/form-data">  
            <s:file name="doc" label="选择上传的文件"/>  
                <s:file name="doc" label="选择上传的文件"/>  
                <s:file name="doc" label="选择上传的文件"/>  
                <s:submit value="上传"/>  
            </s:form>  
                
          </body>  

    listSuccess.jsp

        <body>  
            <h3>使用List上传多个文件 s:iterator显示</h3>  
            <s:iterator value="docFileName" status="st"><s:property value="#st.getIndex()+1"/>个图片:   
                <br/>  
                <img src="image/<s:property value="docFileName.get(#st.getIndex())"/>"/><br/>  
            </s:iterator>  
            <h3>使用List上传多个文件 c:foreach显示</h3>  
            <c:forEach var="fn" items="${docFileName}" varStatus="st">  
                  第${st.index}个图片<br/>  
                 <img src="image/${fn}"/>  
            </c:forEach>  
        </body>  

    案例:Struts2 文件下载

    Struts2支持文件下载,通过提供的stram结果类型来实现。指定stream结果类型是,还需要指定inputName参数,此参数表示输入流,作为文件下载入口。 

    简单文件下载 不含中文附件名

        package com.sh.action;   
          
        import java.io.InputStream;   
          
        import org.apache.struts2.ServletActionContext;   
          
        import com.opensymphony.xwork2.ActionSupport;   
          
        public class MyDownload extends ActionSupport {   
          
            private String inputPath;   
          
            //注意这的  方法名 在struts.xml中要使用到的   
            public InputStream getTargetFile() {   
                System.out.println(inputPath);   
                return ServletActionContext.getServletContext().getResourceAsStream(inputPath);   
            }   
               
            public void setInputPath(String inputPath) {   
                this.inputPath = inputPath;   
            }   
          
            @Override  
            public String execute() throws Exception {   
                // TODO Auto-generated method stub   
                return SUCCESS;   
            }   
               
               
        }  

    Struts.xml

        <action name="mydownload" class="com.sh.action.MyDownload">  
                    <!--给action中的属性赋初始值-->  
                <param name="inputPath">/image/1347372060765110.jpg</param>  
        <!--给注意放回后的 type类型-->  
                <result name="success" type="stream">  
                              <!--要下载文件的类型-->  
                    <param name="contentType">image/jpeg</param>  
                                <!--action文件输入流的方法 getTargetFile()-->  
                    <param name="inputName">targetFile</param>  
                                <!--文件下载的处理方式 包括内联(inline)和附件(attachment)两种方式--->  
                    <param name="contentDisposition">attachment;filename="1347372060765110.jpg"</param>  
                               <!---下载缓冲区的大小-->  
                    <param name="bufferSize">2048</param>  
                </result>  
            </action>  

    down.jsp

        <body>  
                <h3>Struts 2 的文件下载</h3> <br>  
                <a href="mydownload.action">我要下载</a>  
        </body>  

    文件下载,支持中文附件名 

    action

        package com.sh.action;   
          
        import java.io.InputStream;   
          
        import org.apache.struts2.ServletActionContext;   
          
        import com.opensymphony.xwork2.ActionSupport;   
          
        public class DownLoadAction extends ActionSupport {   
          
            private final String DOWNLOADPATH="/image/";   
            private String fileName;   
                 
                //这个方法 也得注意 struts.xml中也会用到   
            public InputStream getDownLoadFile(){   
                return ServletActionContext.getServletContext().getResourceAsStream(DOWNLOADPATH+fileName);   
            }   
            //转换文件名的方法 在strust.xml中会用到   
            public String getDownLoadChineseFileName(){   
                String chineseFileName=fileName;   
                try {   
                    chineseFileName=new String(chineseFileName.getBytes(),"ISO-8859-1");   
                } catch (Exception e) {   
                    e.printStackTrace();   
                }   
                return chineseFileName;   
            }   
            @Override  
            public String execute() throws Exception {   
                // TODO Auto-generated method stub   
                return SUCCESS;   
            }   
          
            public String getFileName() {   
                return fileName;   
            }   
          
            public void setFileName(String fileName) {   
                this.fileName = fileName;   
            }   
               
        }  

    struts.xml

        <action name="download" class="com.sh.action.DownLoadAction">  
                    <param name="fileName">活动主题.jpg</param>  
                    <result name="success" type="stream">  
                        <param name="contentType">image/jpeg</param>  
                                <!-- getDownLoadFile() 这个方法--->  
                        <param name="inputName">downLoadFile</param>  
                        <param name="contentDisposition">attachment;filename="${downLoadChineseFileName}"</param>  
                        <param name="bufferSize">2048</param>  
                    </result>  
         </action>  

    down1.jsp

        <body>  
                <h3>Struts 2 的文件下载</h3> <br>  
                <a href="download.action">我要下载</a>  
          </body>  
  • 相关阅读:
    day23_2_logging
    day23_1-re模块之转义字符、分组、方法
    The Python Standard Library
    re.groups取出来的空元祖??
    Mybatis-学习笔记(2)Mybatis配置文件
    Mybatis-第N篇配置log4j1、log4j2打印执行的sql语句
    Java-数据库连接池第一篇
    Mybatis-学习笔记(1)SqlSessionFactory、SqlSession、Mybatis配置文件configuration的属性标签
    Spring MVC-学习笔记(5)spring MVC的文件上传、下载、拦截器
    Java-多线程第四篇线程池
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/4519988.html
Copyright © 2020-2023  润新知