android网络上传图片数据到服务端

       本次任务:上传安卓客户端的res下的一张图片到服务器端的E盘下。

        自己捣鼓这个作品时也真的费了劲,遇到三个小麻烦搞了两天才搞好。我越来越觉得能有个前辈在身边及时进行辅导能省下很多时间,可能这就是教师的儿女一般学习成绩都不错能上好大学的原因吧,教师比较闲相对来说又不断学习能给子女及时解答。

    遇到的4个错误:

1:不知道怎么获取res下的某个图片的输入流?最后也是网络试了好多个别人的方法,这个通了

  //图片数据难点
               Resources r = HttpImageUpload.this.getBaseContext().getResources();
               //取得对应图片的输入流,图片名字可以和最终写入的文件名不一致
               //图片格式可以是png也可以是jpg
               InputStream is = r.openRawResource(R.drawable.w);

2:一个错误:以为out.flush();包含了发送数据的功能,结果并不是,out.flush()只是清空掉暂时存储在内存缓冲区的所有数据,连接返回一个输入流才是发送数据并返回相应的信息
              InputStream in=con.getInputStream();

3.一个错误无法解决:

服务端报错: Servlet.service() for servlet [android.HttpImageUpload] in context with path [/AndroidServer]threwexception[org.apache.tomcat.util.http.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream

最后发现是请求头Content-Type后面多加了冒号导致的。

4.在开发环境为AndroidStudio中和Eclipse中一模一样的代码,结果始终无法识别R.drawable.baby;

Error:Execution failed for task ':app:compileDebugJava'.
> Compilation failed; see the compiler error output for details.

网上说是开发工具的不一致导致的,在搞搞还是没用,最后用了

@SuppressWarnings("ALL")

错误就消失了,成功运行了,该批注是编译器对某些警告进行忽略的作用。

下面附上代码:

安卓客户端

package internethttp;

import android.content.res.Resources;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
import com.internethttp.R;


public class HttpImageUpload extends Activity {
public Button tv_btn;
    public URL url;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image);
        tv_btn= (Button) findViewById(R.id.tv_btn);
        try {
            url=new URL("http://ly-and-tl.uicp.cn:42696/AndroidServer/HttpImageUpload");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        tv_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                  new httpImgThread(url).start();
            }
        });
    }
   class httpImgThread extends Thread{
      URL URL;
       String prefix="--";//结尾要在分隔符后加这个
//分隔符其实可以很随意指定数字,多少位都行,但注意的是正文比请求头的分隔符多出两个中杠
       String boundary=UUID.randomUUID().toString();
       String end="\r\n";//换行
       httpImgThread(URL l){
         URL=l;
         System.out.println(boundary);
       }
       @Override
       public void run() {
           try {
//        	   第三种请求体的请求体被分成为多个部分,文件上传时会被使用,
//        	   这种格式最先应该是被用于邮件传输中,每个字段/文件都被boundary(Content-Type中指定)分成单独的段,
//        	   每段以-- 加 boundary开头,然后是该段的描述头,描述头之后空一行接内容
               HttpURLConnection con=(HttpURLConnection)URL.openConnection();
               con.setRequestMethod("POST");
               con.setDoOutput(true);//允许输出
               con.setDoInput(true);//允许输入
               //数据类型表单的形式,分隔符指定
               con.setRequestProperty("Connection:", "keep-alive");
               //请求消息头,以表单的形式发送数据到服务端,指定分隔符隔开不同的文件数据
               //muiltipart/form-data可以以二进制方式上传文件
               con.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);
               DataOutputStream out=new DataOutputStream(con.getOutputStream());
               //分隔符换行,正文开始
               out.writeBytes(prefix+boundary+end);
               //指定键名,键值,name是控件的name,根据他后台找出对应图片,一个name标识一个文件
               //含有filename会被当成一个文件
               out.writeBytes("Content-Disposition:form-data;name=\"ooo\";"
+"fliename=\"upload.png\" " +end);
               out.writeBytes(end);
               //图片数据难点
               Resources r = HttpImageUpload.this.getBaseContext().getResources();
               //取得对应图片的输入流,图片名字可以和最终写入的文件名不一致
               //图片格式可以是png也可以是jpg
               InputStream is = r.openRawResource(R.drawable.w);
               byte[] b=new byte[1024*4];
               int len=0;
               //读取图片数据
               while((len=is.read(b))!=-1){
            	   //is输入流读出来暂存到b中
                   out.write(b,0,len);
               //将b中的数据写入out输出流中,从0开始的len个字节
               }
               //换行
               out.writeBytes(end);
               //分隔符换行后面多加--
               out.writeBytes(prefix + boundary + prefix + end);
               //并不发送,是清空缓冲区残存的的数据流
               out.flush();
               //下面才是发送请求并拿到返回的输入流
               InputStream in=con.getInputStream();
               if(out!=null)out.close();
               if(is!=null)is.close();
               if(in!=null) in.close();
               
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
   }
}

服务器端:

package android;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

//servlet3.0后简单的定义网址的方式
@WebServlet("/HttpImageUpload")
//指定文件上传的位置
@MultipartConfig(location="e:\\")//大小写都可以
public class HttpImageUpload extends HttpServlet {
	private static final long serialVersionUID = 1L;
   
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//取出文件,根据前台请求发送的文件名name
//servlet3.0后才有的方法
		Part part=request.getPart("ooo");
//写进文件名为upload.png的文件中
    	part.write("upload.png");
		response.setCharacterEncoding("UTF-8");
	}

}

 

转载于:https://my.oschina.net/u/3630543/blog/1814420

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值