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;

    }


}


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。