文档章节

struts2 图片上传

不打伞的小鱼
 不打伞的小鱼
发布于 2015/05/19 11:20
字数 1263
阅读 131
收藏 2

  struts2本身自带有上传功能,所以只需要导入相应的包即可以使用,具体的哪些包,可以上网搜索,就不一一列举了。

  先看一下前台代码:

<form action="fileUpload_upload" method="post" enctype="multipart/form-data">

                        <table>

                            <tr>

                                <td>上传文件:</td>

                                <td><input type="file" name="myFile"></td>

                            </tr>

                            <tr>

                                <td><input type="submit" value="上传"></td>

                                <td><input type="reset"></td>

                            </tr>

                        </table>

</form>

可以看到点击上传的时候,会调用fileUpload_upload.action,所以要到struts.xml中找到fileUpload_upload.action所对应的是哪个类中的哪个方法。

找到后,是下面这个类:

import java.io.*;


import com.arche.alderman.mvc.base.controller.BaseAction;

import org.apache.struts2.ServletActionContext;


/**

 * Created by hexiaoyu on 2015/5/18.

 */


public class FileUpload extends BaseAction {

    private File myFile;

    private String myFileContentType;

    private String myFileFileName;


    /**

     * 文件上传

     * @return

     * @throws Exception

     */

    public String upload() throws Exception {

       

        InputStream inputStream = new FileInputStream(myFile);

        String uploadPath = ServletActionContext.getServletContext()

                .getRealPath("/");

        File toFile = new File(uploadPath,this.getMyFileFileName());

        OutputStream os = new FileOutputStream(toFile);

        byte[] buffer = new byte[1024];


        int length = 0;

        while ((length = inputStream.read(buffer)) > 0) {

            os.write(buffer, 0, length);

        }


        is.close();

        os.close();


        setServerResponseResult(ResponseStatusCode.REP_SERVER_HANDLE_SUCCESS, myFileFileName+"_"+myFileContentType, null);

        return ServerCommonString.ACTION_RESULT_JSON;

    }


    public File getMyFile() {

        return myFile;

    }

    public void setMyFile(File myFile) {

        this.myFile = myFile;

    }

    public String getMyFileContentType() {

        return myFileContentType;

    }

    public void setMyFileContentType(String myFileContentType) {

        this.myFileContentType = myFileContentType;

    }

    public String getMyFileFileName() {

        return myFileFileName;

    }

    public void setMyFileFileName(String myFileFileName) {

        this.myFileFileName = myFileFileName;

    }


}

此时上传图片是可以成功的,但是缺少:

1.检测后缀名不为图片的文件。

2.检测把后缀名强行改为.jpg的非图片文件。

关于解决第一点,则需要在struts.xml中添加一些文件上传的拦截器配置:


<package name="fileUpload" extends="global">

                <action name="fileUpload_*" class="com.arche.alderman.constant.FileUpload" method="{1}">

                        <result name="result_json" type="json">

                                <param name="root">mResult</param>

                        </result>

                        <!--配置fileUpload的拦截器-->

                        <interceptor-ref name="fileUpload">

                        <!--配置允许上传的文件类型-->

                        <param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>

                        <!--配置允许上传的文件大小单位字节-->

                        <param name="maximumSize">5242880</param>

                        </interceptor-ref>

                        <interceptor-ref name="defaultStack"/>

                </action>

        </package>

由于fileUpload这个拦截器是struts2自带的,所以可以直接使用,然后配置允许上传的文件类型和最大字节。这样就解决了第一个问题。

然后就是第二个,如何判断文件是否是图片文件了,这时候我在osc上问了一些大神,大家说可以用判断文件头的方式解决,我试了下,可以成功,只需要在上面的FileUpload这个类中再添加两个方法:

/**

     * 得到上传文件的文件头

     * @param src

     * @return

     */

    public static String bytesToHexString(byte[] src){

        StringBuilder stringBuilder = new StringBuilder();

        if (src == null || src.length <= 0) {

            return null;

        }

        for (int i = 0; i < src.length; i++) {

            int v = src[i] & 0xFF;

            String hv = Integer.toHexString(v);

            if (hv.length() < 2) {

                stringBuilder.append(0);

            }

            stringBuilder.append(hv);

        }

        return stringBuilder.toString();

    }


    /**

     * 根据制定文件的文件头判断其文件类型

     * @param is

     * @return

     */

    public static String getTypeByStream(InputStream is){

        byte[] b = new byte[4];

        try {

            is.read(b, 0, b.length);

        } catch (IOException e) {

            e.printStackTrace();

        }

        String type = bytesToHexString(b).toUpperCase();

        if(type.contains("FFD8FF") || type.contains("89504E47") || type.contains("49492A00") || type.contains("424D")){

            return "isImage";

        }

        return "notImage";

    }

然后在得到inputStream的时候,调用

getTypeByStream()方法,把inputStream传进去,就可以判断是不是图片文件了

这里需要特别注意的是,传进去的inputStream会去掉文件头,所以最后上传的图片是已经损坏的,我没想到什么好的办法,就是创建了一个新的inputStream,把这个新的再拿去上传,这两个互不影响,测试是可以通过的。贴下完整的FileUpload.java供参考:


import java.io.*;


import com.arche.alderman.mvc.base.controller.BaseAction;

import org.apache.struts2.ServletActionContext;


/**

 * Created by hexiaoyu on 2015/5/18.

 */


public class FileUpload extends BaseAction {

    private File myFile;

    private String myFileContentType;

    private String myFileFileName;


    /**

     * 得到上传文件的文件头

     * @param src

     * @return

     */

    public static String bytesToHexString(byte[] src){

        StringBuilder stringBuilder = new StringBuilder();

        if (src == null || src.length <= 0) {

            return null;

        }

        for (int i = 0; i < src.length; i++) {

            int v = src[i] & 0xFF;

            String hv = Integer.toHexString(v);

            if (hv.length() < 2) {

                stringBuilder.append(0);

            }

            stringBuilder.append(hv);

        }

        return stringBuilder.toString();

    }


    /**

     * 根据制定文件的文件头判断其文件类型

     * @param is

     * @return

     */

    public static String getTypeByStream(InputStream is){

        byte[] b = new byte[4];

        try {

            is.read(b, 0, b.length);

        } catch (IOException e) {

            e.printStackTrace();

        }

        String type = bytesToHexString(b).toUpperCase();

        if(type.contains("FFD8FF") || type.contains("89504E47") || type.contains("49492A00") || type.contains("424D")){

            return "isImage";

        }

        return "notImage";

    }


    /**

     * 文件上传

     * @return

     * @throws Exception

     */

    public String upload() throws Exception {


        InputStream is = new FileInputStream(myFile);

        if ("notImage".equals(getTypeByStream(is))){

            setServerResponseResult(-1, "file type error", null);

            return ServerCommonString.ACTION_RESULT_JSON;

        }

        InputStream inputStream = new FileInputStream(myFile);

        String uploadPath = ServletActionContext.getServletContext()

                .getRealPath("/");

        File toFile = new File(uploadPath,this.getMyFileFileName());

        OutputStream os = new FileOutputStream(toFile);

        byte[] buffer = new byte[1024];


        int length = 0;

        while ((length = inputStream.read(buffer)) > 0) {

            os.write(buffer, 0, length);

        }


        is.close();

        os.close();


        setServerResponseResult(ResponseStatusCode.REP_SERVER_HANDLE_SUCCESS, myFileFileName+"_"+myFileContentType, null);

        return ServerCommonString.ACTION_RESULT_JSON;

    }


    public File getMyFile() {

        return myFile;

    }

    public void setMyFile(File myFile) {

        this.myFile = myFile;

    }

    public String getMyFileContentType() {

        return myFileContentType;

    }

    public void setMyFileContentType(String myFileContentType) {

        this.myFileContentType = myFileContentType;

    }

    public String getMyFileFileName() {

        return myFileFileName;

    }

    public void setMyFileFileName(String myFileFileName) {

        this.myFileFileName = myFileFileName;

    }


}

         




2015-05-21 补充:上面的功能2的实现,博客中用的是通过文件头的方式去判断,但是文件头也是可以人为修改的。今天在老大的带领下,找到了一个更好的方法:获取上传文件的宽度和高度。如果存在,则一定为图片,如果不存在,则说明不是图片文件。

BufferedImage image = null;

        try {

            image = ImageIO.read(mFileVO.getFiles().get(0));

            if (null == image){

                setServerResponseResult(REP_SERVER_HANDLE_ERROR, ValidateString.FILE_TYPE_ERROR, null);

                return ACTION_RESULT_JSON;

            }

            int width = image.getWidth();

            int height = image.getHeight();

        } catch (IOException e) {

            e.printStackTrace();

        }

说明:当传入的file对象是图片时,image不为空,可以正确得到高度和宽度,而当把一个.txt文件改成.jpg格式,然后上传后,image的值为null.




© 著作权归作者所有

不打伞的小鱼
粉丝 70
博文 42
码字总数 24218
作品 0
深圳
程序员
私信 提问
struts2整合CKEditor和CKFinder实现上传

上一篇文章给大家分享了CKEditor+CKFinder+JSP实现了在线编辑器上传图片的功能,这里在给大家分享一下如何在前面的基础上在struts2下实现这样的功能。 实现与Struts2的整合,整合的过程确实e...

teacheryang
2016/10/08
0
0
问一下struts2用ajax上传图片的问题

问一下struts2用ajax上传图片的问题 用struts2上传的方式。但是不行。 百度谷歌了半了发现应该是ajax安全机制问题。传到后台的不是数据流。 而是字符串。但是如何处理这些字符串呢?...

th小米粥
2011/11/03
851
1
使用Struts2上传图片

在Struts2中为我们提供了比较简单的文件上传方式. 首先引入commons-fileupload-x.jar、commons-io-x.jar 这两个jar包,然后引入Struts2相关jar包 接下来新建一个jsp文件:写一个文件上传表单,...

小和尚敲代码
2016/02/03
97
0
求javaWeb编程高手!!关于struts上传文件的问题~~

我利用struts2完成了上传功能,将上传的图片存储在tomcat服务器的webapp的该项目的文件夹下,struts上传代码是这样的: 上传后不久,图片连同文件夹就会消失的无影无踪,问了一个学长,他说这...

上帝爱众生
2014/05/16
157
0
简单解决Struts2和FckEditor冲突的方法

最近用了struts2.0之后,fck上传图片总是弹出警告: Security error. You probably don't have enough permissions to upload. Please check your server 什么原因呢? 一般情况下跟你的web......

oecp
2011/04/14
237
2

没有更多内容

加载失败,请刷新页面

加载更多

rime设置为默认简体

转载 https://github.com/ModerRAS/ModerRAS.github.io/blob/master/_posts/2018-11-07-rime%E8%AE%BE%E7%BD%AE%E4%B8%BA%E9%BB%98%E8%AE%A4%E7%AE%80%E4%BD%93.md 写在开始 我的Arch Linux上......

zhenruyan
今天
4
0
简述TCP的流量控制与拥塞控制

1. TCP流量控制 流量控制就是让发送方的发送速率不要太快,要让接收方来的及接收。 原理是通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小。...

鏡花水月
今天
8
0
OSChina 周日乱弹 —— 别问,问就是没空

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享容祖儿/彭羚的单曲《心淡》: 《心淡》- 容祖儿/彭羚 手机党少年们想听歌,请使劲儿戳(这里) @wqp0010 :周...

小小编辑
今天
876
10
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
5
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部