我的漫漫程序之旅

专注于JavaWeb开发
随笔 - 39, 文章 - 310, 评论 - 411, 引用 - 0
数据加载中……

HttpURLConnection上传文件(图片)小试

需求:用HttpURLConnection模拟上传图片并把图片的名称也要传递过去.

简单分析:写入流的时候依次写入 图片名称 + "|" 分隔符 +  图片流

然后服务器接收的再处理流.分别取出图片名和图片.

/**
     * 上传方法
     * 返回上传完毕的文件名
     * *
     
*/

    
public String upload(File f)
    
{
        
try
        
{
            
//服务器IP(这里是从属性文件中读取出来的)
            String hostip = FileSupport.getServerIP();
            URL url 
= new URL("http://"+ hostip +"/oxServer/ReceiveServlet");
            
            HttpURLConnection uc 
= (HttpURLConnection) url.openConnection();
            
//上传图片的一些参数设置
            uc
                    .setRequestProperty(
                            
"Accept",
                            
"image/gif,   image/x-xbitmap,   image/jpeg,   image/pjpeg,   application/vnd.ms-excel,   application/vnd.ms-powerpoint,   application/msword,   application/x-shockwave-flash,   application/x-quickviewplus,   */*");
            uc.setRequestProperty(
"Accept-Language""zh-cn");
            uc
                    .setRequestProperty(
"Content-type",
                            
"multipart/form-data;   boundary=---------------------------7d318fd100112");
            uc.setRequestProperty(
"Accept-Encoding""gzip,   deflate");
            uc
                    .setRequestProperty(
"User-Agent",
                            
"Mozilla/4.0   (compatible;   MSIE   6.0;   Windows   NT   5.1)");
            uc.setRequestProperty(
"Connection""Keep-Alive");
            uc.setDoOutput(
true);
            uc.setUseCaches(
true);
        
            
//读取文件流
            int size = (int) f.length();
            
byte[] data = new byte[size];
            FileInputStream fis 
= new FileInputStream(f);
            OutputStream out 
= uc.getOutputStream();
            fis.read(data, 
0, size);
            
//写入文件名
            out.write(f.getName().trim().getBytes());
            
//写入分隔符
            out.write('|');
            
//写入图片流
            out.write(data);
            out.flush();
            out.close();
            fis.close();
            
            
//读取响应数据
            int code = uc.getResponseCode();
            String sCurrentLine 
= "";
            
//存放响应结果
            String sTotalString = "";
            
if (code == 200)
            
{
                java.io.InputStream is 
= uc.getInputStream();
                BufferedReader reader 
= new BufferedReader(
                        
new InputStreamReader(is));
                
while ((sCurrentLine = reader.readLine()) != null)
                    
if (sCurrentLine.length() > 0)
                        sTotalString 
= sTotalString + sCurrentLine.trim();
            }

            
else
            
{
                sTotalString 
= "远程服务器连接失败,错误代码:" + code;
            }

            
return sTotalString;
        }

        
catch (Exception e)
        
{
            e.printStackTrace();
        }

        
return null;
    }


服务器Servlet:
public void doGet(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, IOException
    
{
        ServletInputStream inStream 
= request.getInputStream(); // 取HTTP请求流
        int size = request.getContentLength(); // 取HTTP请求流长度

        
byte[] buffer = new byte[size]; // 用于缓存每次读取的数据
        byte[] result = new byte[size]; // 用于存放结果的数组
        int count = 0;
        
int rbyte = 0;
        
// 循环读取
        while (count < size)
        
{
            rbyte 
= inStream.read(buffer); // 每次实际读取长度存于rbyte中 sflj
            for (int i = 0; i < rbyte; i++)
            
{
                result[count 
+ i] = buffer[i];
            }

            count 
+= rbyte;
        }


        
// 先找到文件名和图片流的标志位'|'
        int index = 0;
        
for (int i = 0; i < result.length; i++)
        
{
            
byte b = result[i];
            
if (b == '|')
            
{
                index 
= i;
                
break;
            }

        }


        
// 存放文件名
        byte name[] = new byte[index + 1];
        
// 存放图片字节
        byte[] img = new byte[size - index];
        
for (int i = 0; i < result.length; i++)
        
{
            
if (i < index)
            
{
                name[i] 
= result[i];
            }

            
if (i > index)
            
{
                
// 这时注意img数组的index要从0开始
                img[i - index - 1= result[i];
            }

        }

        
// 还原文件名
        String fileName = new String(name);

        inStream.close();

        String newFileName 
= renameFile(fileName);
        
// 响应客户端
        response.setContentType("text/html");
        
// 注意响应中文数据时要设置
        response.setCharacterEncoding("GBK");
        PrintWriter out 
= response.getWriter();
        
//可能情况 0 数据库无相关记录 1 文件名不符合要求 其它情况为正常
        if(newFileName.equals("0"))
        
{
            out.write(
"0|" + fileName);
        }

        
else if(newFileName.equals("1"))
        
{
            out.write(
"1|" + fileName);
        }

        
else
        
{
            out.write(fileName);
        }

        out.close();
        
//上传错误中止后续操作
        if(newFileName.length()<= 1)
        
{
            
return;
        }

        
        File f 
= new File(ImageSupport.getOriginal() + "/" + newFileName);
        FileOutputStream fos 
= new FileOutputStream(f);
        fos.write(img);
        fos.flush();
        fos.close();
        
// 改变图片大小后重新放置到新地点
        ImageSupport.changeImageSize(f, ImageSupport.getAfter() + "/"
                
+ newFileName, 300300);
    }


我写的是一个批量上传图片的程序,经测试通过.

posted on 2009-02-06 11:54 々上善若水々 阅读(7573) 评论(7)  编辑  收藏

评论

# re: HttpURLConnection上传文件(图片)小试  回复  更多评论   

学习 学习 你说的批量上传是一次传一个 传多次,还是一次就传多个上去。
2009-02-06 12:41 | blackbat

# re: HttpURLConnection上传文件(图片)小试  回复  更多评论   

@blackbat
一次传一个.不过用户体验到的是批量.
2009-02-06 13:00 | 々上善若水々

# re: HttpURLConnection上传文件(图片)小试  回复  更多评论   

要是在客户端直接用java编写程序上传文件,直接用tcp传二进制流就可以(当然,这要服务端也是自己实现),模拟http上传效率有些低。
2009-02-06 13:27 | 银河使者

# re: HttpURLConnection上传文件(图片)小试  回复  更多评论   

@银河使者
那样的话是不是就像QQ一样啊.可以直接传送整个文件夹.对tcp接触少.
2009-02-06 13:50 | 々上善若水々

# re: HttpURLConnection上传文件(图片)小试  回复  更多评论   

@々上善若水々
就是传送二进制(字节流),至于字节流里是什么,完全由用户自己定义,当然可以是文件夹里的内容,而且都自己实现还是个好处,可以实现断点上传功能。甚至是多线程上传。在服务端利用Servlet就可以实现。
2009-02-06 14:37 | 银河使者

# re: HttpURLConnection上传文件(图片)小试  回复  更多评论   

@银河使者
还支持断点?早知道就用tcp了.谢谢,有时间再尝试一下.
2009-02-06 15:06 | 々上善若水々

# re: HttpURLConnection上传文件(图片)小试  回复  更多评论   

@楼上
那样的话就搞成C/S了,客户端服务端的代码都得写。
2009-02-07 17:06 | blackbat

只有注册用户登录后才能发表评论。


网站导航: