Android,Okhttp上传图片到服务器,从服务器下载图片

Okhttp+Tomcat+struts(上传图片)+Servlet(下载图片)

前言

在Android项目开发中,少不了需要将用户上传的图片保存,比如用户上传更新头像。如果不把图片保存到服务器,而是保存到本地,那么用户删除本地数据(如卸载应用,再下载回),用户的图片数据就会丢失,并且用户也无法访问到其他用户的图片数据,因为数据保存在本地是无法实现网络共享。
我曾将图片转为base64的String类型,上传服务器,存储在数据库,后来,由于数据库查询效率实在是低,并且还存不了高清大图,就放弃了这个方式。现在想想,当时真的笨,
作者做的这个只是个Demo,服务器没有用云服务器,而是基于TomCat搭建的本地服务器,要是有任何不合理的地方,欢迎指出。

服务器端

项目目录:

Android,Okhttp上传图片到服务器,从服务器下载图片

03.jsp表单信息

<body>
	<h2>&nbsp; 文件上传	</h2>
  	<form action="upload.action" method="post" enctype="multipart/form-data">
  		上传文件:<input type="file" name="upload"><br>
  		<input type="submit" value="提交">${result}
  	</form>
  </body>

error.jsp上传图片错误跳转的界面

<body> 
    <h2>上传失败!</h2>
    <s:fielderror></s:fielderror>
  </body>

web.xml配置

</welcome-file-list>
 
      <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>DownloadServlet</servlet-name>
        <servlet-class>com.ilikexy.DownloadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>DownloadServlet</servlet-name>
    <url-pattern>/downloadServlet.do</url-pattern>
      </servlet-mapping>

struts.xml配置

<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default"> 
    <action name="upload" class="com.ilikexy.FileUploadAction">
			<result>/jsp/03.jsp</result>
			<result name="input">/jsp/error.jsp</result>
			<!-- 配置拦截器限制上传文件类型及大小 -->
			<interceptor-ref name="fileUpload">
				<param name="allowedTypes">image/*</param>
				<param name="maximumSize">2M</param>
			</interceptor-ref>
			<interceptor-ref name="defaultStack"></interceptor-ref>
			</action>
    </package>
</struts>

上传图片的Action处理类FileUploadAction.java

public class FileUploadAction extends ActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
    //图片
	private List<File> upload;
	
	private List<String> uploadContentType;
	
	private List<String> uploadFileName;
	
	//
	
	private String result;
	
	@Override
	public String execute() throws Exception {
		System.out.println("已经触发了上传函数");
		String path = ServletActionContext.getServletContext().getRealPath("/images");
		File file = new File(path);
		if(!file.exists()){//要是文件夹不存在就创建文件夹
			file.mkdir();
		}
		//循环将批量上传的文件保存到本地
		for(int i=0;i<upload.size();i++){
			File fileer = new File(file,uploadFileName.get(i));//文件 = 文件夹 + 文件名
			FileUtils.copyFile(upload.get(i),fileer);//用FileUtils复制并写入文件,两个参数,一个是文件, 一个是空文件
			System.out.println(""+fileer.getAbsolutePath());
		}
		
		result="上传成功!";
		
		return SUCCESS;
	}
	
	
	
	
	
	
	public List<File> getUpload() {
		return upload;
	}

	public void setUpload(List<File> upload) {
		this.upload = upload;
	}

	public List<String> getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(List<String> uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public List<String> getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(List<String> uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}
}

下载文件的Servlet类 DownloadServlet.java

public class DownloadServlet extends HttpServlet {

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		//获取文件下载路径
		String path = getServletContext().getRealPath("/") + "images/";
        String filename = req.getParameter("filename");
		
		File file = new File(path + filename);
		if(file.exists()){
			//设置相应类型application/octet-stream
			resp.setContentType("application/x-msdownload");
			//设置头信息
			resp.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
			InputStream inputStream = new FileInputStream(file);
			ServletOutputStream ouputStream = resp.getOutputStream();
			byte b[] = new byte[1024];
			int n ;
			while((n = inputStream.read(b)) != -1){
				ouputStream.write(b,0,n);//以字符的形式传输
			}
			//关闭流、释放资源
			ouputStream.close();
			inputStream.close();
			
			
		}else{
			System.out.println("文件不存在下载失败!");
			resp.setContentType("text/html;charset=utf-8");
			PrintWriter writer = resp.getWriter();
			writer.write("文件不存在下载失败!");
			writer.close();
		}
		
		
	}

测试一下效果
Android,Okhttp上传图片到服务器,从服务器下载图片
Android,Okhttp上传图片到服务器,从服务器下载图片
然后我们就可以在输出的路径里找到这个张图片:
Android,Okhttp上传图片到服务器,从服务器下载图片

既然服务器端的功能已经实现了,那么就看一下Android客户端,Okhttp如何post上传图片,如何get请求获取图片:

上传图片关键代码:

//网络请求,将图片数据发给服务器
    public void sendToServer(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                //所有图片类型
                MediaType mediaType=MediaType.Companion.parse("image/*; charset=utf-8");
                //第一层,说明数据为文件,以及文件类型
                RequestBody fileBody=RequestBody.Companion.create(fileer,mediaType);

                //第二层,指明服务表单的键名,文件名,文件体
                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("upload",fileer.getName(),fileBody)
                        .build();
                Request request = new Request.Builder()
                        .url("http://192.168.3.6:8888/DemoStrut/upload.action")
                        .post(requestBody)
                        .build();
                //发送请求
                Call call = client.newCall(request);
                call.enqueue(new Callback() {
                    @Override
                    public void onFailure( Call call, IOException e) {
                        //网络故障
                        Looper.prepare();
                        Toast.makeText(MainActivity.this,"网络故障!",Toast.LENGTH_SHORT).show();
                        Looper.loop();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        if (response.body()!=null){
                            Looper.prepare();
                            //Toast.makeText(MainActivity.this,response.body().string(),Toast.LENGTH_SHORT).show();
                            Log.d("theresult",response.body().string());
                            Looper.loop();
                        }
                    }
                });


            }
        }).start();
    }

下载图片关键代码:

//网络请求,下载图片
    public void downloadFromServer(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client  = new OkHttpClient();
                Request request = new Request.Builder()
                        .url("http://192.168.3.6:8888/DemoStrut/downloadServlet.do?filename=wenzhang6.png")
                        .build();
                Call call = client.newCall(request);
                call.enqueue(new Callback() {
                    @Override
                    public void onFailure( Call call, IOException e) {
                        //网络故障
                        Looper.prepare();
                        Toast.makeText(MainActivity.this,"网络故障!",Toast.LENGTH_SHORT).show();
                        Looper.loop();
                    }

                    @Override
                    public void onResponse( Call call, Response response) throws IOException {
                        //把接收到的流转化为bitmap
                        InputStream in = response.body().byteStream();
                        Bitmap bitmap = BitmapFactory.decodeStream(in);
                        runOnUiThread(new Runnable() {//子线程更新ui
                            @Override
                            public void run() {
                            //这个是图片控件
                                picturehere.setImageBitmap(bitmap);
                            }
                        });
                    }
                });
            }
        }).start();
    }

效果
Android,Okhttp上传图片到服务器,从服务器下载图片

有任何问题欢迎评论区讨论,一起加油,谢谢了。

上一篇:android开发者!京东面试真题解析,完整版开放下载


下一篇:XML解析之sax解析案例(一)读取contact.xml文件,完整输出文档内容