关于Java后台处理android上传图片的问题

来源:互联网 发布:云计算市场份额排名 编辑:程序博客网 时间:2024/05/16 17:57

最近一直被一个问题困扰,就是android上传图片到服务器,但是最终都没能获得图片,不知道是什么原因,先晒出后台代码(该代码也是参考网上大多数网友的写法)

主要用到两个jar包,分别是commons-io 以及commons-fileupload,网上可以下载的到


package servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadHandleServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 得到上传文件的保存目录
        String savePath = this.getServletContext().getRealPath(
                "upload");

        // 上传时生成的临时文件保存目录
        String tempPath = this.getServletContext().getRealPath("temp");
        System.out.println(tempPath);
        File tmpFile = new File(tempPath);

        // 判断上传文件的保存目录是否存在
        if (!tmpFile.exists()) {
            // 创建临时目录
            tmpFile.mkdir();
        }
        // 消息提示
        String message = "";
        try {
            // 使用Apache文件上传组件处理文件上传步骤:
            // 1、创建一个DiskFileItemFactory工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();

         
            // 设置上传时生成的临时文件的保存目录
            factory.setRepository(tmpFile);

            // 2、创建一个文件上传解析器
            ServletFileUpload upload = new ServletFileUpload(factory);

     //此处是为了监听上传文件的进度,可有可无

            upload.setProgressListener(new ProgressListener() {
                public void update(long pBytesRead, long pContentLength,
                        int arg2) {
                    System.out.println("文件大小为:" + pContentLength + ",当前已处理:"
                            + pBytesRead);

                }
            });

            // 解决上传文件名的中文乱码
            upload.setHeaderEncoding("UTF-8");
            // 3、判断提交上来的数据是否是上传表单的数据
            if (!ServletFileUpload.isMultipartContent(request)) {
                // 按照传统方式获取数据
                return;
            }
            
             upload.setFileSizeMax(1024*1024);
             upload.setSizeMax(1024*1024*10);
            
            
            
            // 4、使用ServletFileUpload解析器解析上传数据
            List<FileItem> list = upload.parseRequest(request);

      //此处出现的问题好多







            for (FileItem item : list) {
                // 如果fileitem中封装的是普通输入项的数据
                if (item.isFormField()) {
                    String name = item.getFieldName();
                    // 解决普通输入项的数据的中文乱码问题
                    String value = item.getString("UTF-8");
                    // value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + "=" + value);
                } else {// 如果fileitem中封装的是上传文件
                    // 得到上传的文件名称,
                    String filename = item.getName();
                    System.out.println(filename);
                    if (filename == null || filename.trim().equals("")) {
                        continue;
                    }
                    // 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:
                    // c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
                    // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                    filename = filename
                            .substring(filename.lastIndexOf("\\") + 1);
                    // 获取item中的上传文件的输入流
                    InputStream in = item.getInputStream();
                    // 创建一个文件输出流
                    FileOutputStream out = new FileOutputStream(savePath + "\\"
                            + filename);
            
                    byte buffer[] = new byte[1024];
                    // 判断输入流中的数据是否已经读完的标识
                    int len = 0;
                
                    while ((len = in.read(buffer)) > 0) {
                        // 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"
                        // + filename)当中
                        out.write(buffer, 0, len);
                    }
                    // 关闭输入流
                    in.close();
                    // 关闭输出流
                    out.close();
                    // 删除处理文件上传时生成的临时文件
                    item.delete();
                    message = "文件上传成功!";
                }
            }
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "单个文件超出最大值!!!");
            request.getRequestDispatcher("/pages/message.jsp").forward(request,
                    response);
            return;
        } catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "上传文件的总的大小超出限制的最大值!!!");
            request.getRequestDispatcher("/message.jsp").forward(request,
                    response);
            return;
        } catch (Exception e) {
            message = "文件上传失败!";
            e.printStackTrace();

        }
        request.setAttribute("message", message);
        request.getRequestDispatcher("/pages/message.jsp").forward(request,
                response);
    }

    
    private String makePath(String filename,String savePath){
       
                 int hashcode = filename.hashCode();
                 int dir1 = hashcode&0xf;  //0--15
                 int dir2 = (hashcode&0xf0)>>4;  //0-15
                 //构造新的保存目录
                 String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
                 //File既可以代表文件也可以代表目录
                 File file = new File(dir);
                //如果目录不存在
                 if(!file.exists()){
                     //创建目录
               file.mkdirs();
                 }
                 return dir;
             }
    
     private String makeFileName(String filename){  //2.jpg
             
                  return UUID.randomUUID().toString() + "_" + filename;
              }
    
    
    
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }
}

 List<FileItem> list = upload.parseRequest(request) 为什么获得list集合为空,参考网上意见,是因为Struts本身自带过滤,如下:

修改前:

<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

修改后:

<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>

但是我没有用到struts,仅仅只是用了servlet,所以对我不适用,还是县晒出我的web.xml里面的配置:

<servlet>
     <servlet-name>UploadHandleServlet</servlet-name>
    <servlet-class>servlet.UploadHandleServlet</servlet-class>
 </servlet>
 
<servlet-mapping>
    <servlet-name>UploadHandleServlet</servlet-name>
    <url-pattern>/servlet/UploadHandleServlet</url-pattern>
 </servlet-mapping> 
为什么获取不到图片呢,忘记说了,android不是我写的,所以没有办法晒出前端代码,网上的android 前端好多这么写的:

  1. package com.example.photo;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.DataOutputStream;  
  5. import java.io.File;  
  6. import java.io.FileInputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.io.InputStreamReader;  
  10. import java.io.OutputStream;  
  11. import java.net.HttpURLConnection;  
  12. import java.net.MalformedURLException;  
  13. import java.net.URL;  
  14. import java.util.UUID;  
  15.   
  16.   
  17. public class HttpAssist {  
  18.     private static final String TAG = "uploadFile";  
  19.     private static final int TIME_OUT = 10 * 10000000// 超时时间  
  20.     private static final String CHARSET = "utf-8"// 设置编码  
  21.     public static final String SUCCESS = "1";  
  22.     public static final String FAILURE = "0";  
  23.   
  24.     public static String uploadFile(File file) {  
  25.         String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成  
  26.         String PREFIX = "--", LINE_END = "\r\n";  
  27.         String CONTENT_TYPE = "multipart/form-data"// 内容类型  
  28.         String RequestURL = "http://192.168.0.100:7080/YkyPhoneService/Uploadfile1";  
  29.         try {  
  30.             URL url = new URL(RequestURL);  
  31.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  32.             conn.setReadTimeout(TIME_OUT);  
  33.             conn.setConnectTimeout(TIME_OUT);  
  34.             conn.setDoInput(true); // 允许输入流  
  35.             conn.setDoOutput(true); // 允许输出流  
  36.             conn.setUseCaches(false); // 不允许使用缓存  
  37.             conn.setRequestMethod("POST"); // 请求方式  
  38.             conn.setRequestProperty("Charset", CHARSET); // 设置编码  
  39.             conn.setRequestProperty("connection""keep-alive");  
  40.             conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="  
  41.                     + BOUNDARY);  
  42.             if (file != null) {  
  43.                 /** 
  44.                  * 当文件不为空,把文件包装并且上传 
  45.                  */  
  46.                 OutputStream outputSteam = conn.getOutputStream();  
  47.   
  48.                 DataOutputStream dos = new DataOutputStream(outputSteam);  
  49.                 StringBuffer sb = new StringBuffer();  
  50.                 sb.append(PREFIX);  
  51.                 sb.append(BOUNDARY);  
  52.                 sb.append(LINE_END);  
  53.                 /** 
  54.                  * 这里重点注意: name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件 
  55.                  * filename是文件的名字,包含后缀名的 比如:abc.png 
  56.                  */  
  57.   
  58.                 sb.append("Content-Disposition: form-data; name=\"img\"; filename=\""  
  59.                         + file.getName() + "\"" + LINE_END);  
  60.                 sb.append("Content-Type: application/octet-stream; charset="  
  61.                         + CHARSET + LINE_END);  
  62.                 sb.append(LINE_END);  
  63.                 dos.write(sb.toString().getBytes());  
  64.                 InputStream is = new FileInputStream(file);  
  65.                 byte[] bytes = new byte[1024];  
  66.                 int len = 0;  
  67.                 while ((len = is.read(bytes)) != -1) {  
  68.                     dos.write(bytes, 0, len);  
  69.                 }  
  70.                 is.close();  
  71.                 dos.write(LINE_END.getBytes());  
  72.                 byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END)  
  73.                         .getBytes();  
  74.                 dos.write(end_data);  
  75.                 dos.flush();  
  76.                 /** 
  77.                  * 获取响应码 200=成功 当响应成功,获取响应的流 
  78.                  */  
  79.                 int res = conn.getResponseCode();  
  80.                 if (res == 200) {  
  81.                     return SUCCESS;  
  82.                 }  
  83.             }  
  84.         } catch (MalformedURLException e) {  
  85.             e.printStackTrace();  
  86.         } catch (IOException e) {  
  87.             e.printStackTrace();  
  88.         }  
  89.         return FAILURE;  
  90.     }  

  sb.append("Content-Disposition: form-data; name=\"img\"; filename=\""  


  •                         + file.getName() + "\"" + LINE_END); 

      sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""  


  •                         + file.getName() + "\"" + LINE_END); 


    这两者有什么区别,有大神知道的说一下 啊












  • 1 0
    原创粉丝点击