struts2 图片上传

  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.




转载于:https://my.oschina.net/xiaoyuHe/blog/416613

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值