Android与后端(javaweb)数据交互,包含文件(流传输)、json、html文本
Android向前端发送数据
一般需要交互的数据无非就是文件和字符串(可以替代很多东西),文件又可以变为字符串流进行传输。本文将使用okhttp包从Android端向后端发送数据和接收返回数据。
注意:个人电脑测试若无https协议的域名或ip地址,请在Android的AndroidManifest.xml文件中声明使用明文传输,既不加密使用http协议。
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:usesCleartextTraffic="true"//此处默认选项为false,不启用明文传输,改为true即可 android:theme="@style/AppTheme"> </application>
数据发送,Android端向客户端发送消息如果为get直接在url中添加参数即可,下面主要介绍post,用字符串作为post参数,文件将经过base64编码为字符串传输,字符串类型数据可采用json传输也可以直接用字符串。注意:okhttp包需额外下载,包含okhttp和okio两个包且版本存在不适配问题,需要对应,这里采用okhttp3.12, okio1.14。如果使用grade(一般Android都是这个),可直接在build.grade中使用implementation group: 'com.squareup.okio', name: 'okio', version: '1.14.0'
导入,建议下载对应包。
注意:数据发送操作(向网络申请数据)为耗时操作,不可在主线程中运行,另外不建议直接在oncreate等视图创建方法中调用,可以作为按钮点击事件调用。另外收sdk限制同时会限制jdk版本,这里使用的base64编码是Android自带的,与稍后后端解析时的不同。以为jdk版本原因及编码规范,存在不同格式的base64编码,Androidsdk26以上可采用java自带的base64编码工具。
new Thread() { //重写线程run方法 @Override public void run() { //定义okhttp对象 OkHttpClient okHttpClient = new OkHttpClient(); try { //如果传输文件 FileInputStream inputStream = new FileInputStream(new File(getDataDir() + "/x1.png")); //文件读取为bytes byte[] bytes = new byte[inputStream.available()]; inputStream.read(bytes); //将bytes使用base64编码 String a1 = Base64.encodeToString(bytes, Base64.NO_PADDING); //post的方法体,用来添加数据(key-value方式),但只能添加字符串作为数据 FormBody formBody = new FormBody.Builder().add("w1", a1).add("w2", "wad").build(); //请求创建 Request request = new Request.Builder().url("http://192.168.56.1:8080/titan/login").post(formBody).build(); //执行请求 Call call = okHttpClient.newCall(request); Response response = call.execute();//获得服务端返回内容 //将返回内容作为字符串输出,也可转换为bytes等 System.out.println(response.body().string());} catch (IOException e) { e.printStackTrace(); } } }.start();//线程直接启动
服务端接收与返回数据
项目使用tomcat,利用struts的action请求和返回数据。action可返回不限于json、html网页、流格式的内容。项目大致结构如下。
其中images文件夹作为Android端文件存储库和返回信息库,一般不建议将此类文件放入项目内,一个是通过相对路径不方便调取(存在诸多问题,所以放在外边采用绝对路径访问),还有就是对于tomcat下webapps的内容均可以通过url访问,文件直接就泄露了。index.jsp并无什么用,只是默认主页。
struts.xml配置文件,此文件build完成时需在WEB-INF/classes文件夹下,关于在web.xml里配置struts不再给出
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"><struts>//此包用于返回json数据,继承json-default包,也可通过result-types指定,不再介绍 <package name="backJOSN" extends="json-default"> //活动配置,负责返回json数据,可以返回json文件或者自定义json串,这里是有action内部变量组成的json串 <action name="login" class="com.example.titanback.LoginAction"> <result type="json"> </result> </action> </package> //继承默认包,可返回文件流或者html文件文本 <package name="backHTML" extends="struts-default"> //返回图片的活动 <action name="imgBack" class="com.example.titanback.ImgBackAction"> <result type="stream">//返回流 //配置返回流,返回png格式图片,并配置对应变量 <param name="contentType">image/png</param> <param name="inputStream">inputStream</param> </result> </action> </package></struts>
代码,此代码将返回json字符串
//可继承Action接口或继承ActionSupport类public class LoginAction extends ActionSupport{//变量和setter、getter方法 private String username; private String password; public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public String getUsername() { return username; } public void setPassword(String password) { this.password = password; } @Override public String execute() throws Exception {//获取上下文,getResponse可获取response对象 HttpServletRequest actionContext = ServletActionContext.getRequest(); //输出获取参数 System.out.println(actionContext.getParameter("w1")); String a1 = actionContext.getParameter("w1"); //文件写入流,采用绝对路径 FileOutputStream outputStream = new FileOutputStream("C:\\Users\\1\\Desktop\\Titan\\titanback\\images\\x1.png"); //将base64解码,注意以为jdk原因,需要去掉换行符,最好采用utf-8编码 ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64.getMimeDecoder().decode(a1.replace("\r\n", "").getBytes(StandardCharsets.UTF_8))); //输出流直接转换 inputStream.transferTo(outputStream); outputStream.close();//关闭 setUsername("w112");//设置参数 setPassword("wdaw"); return SUCCESS; }}
注意:关于base64编码问题,请看:这里
此代码将返回png格式图片流,
public class ImgBackAction implements Action{//要返回的变量 private InputStream inputStream; public InputStream getInputStream() { return inputStream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } @Override public String execute() throws Exception {//绝对路径打开文件,并获取流 FileInputStream inputStream = new FileInputStream(new File("C:\\Users\\1\\Desktop\\Titan\\titanback\\images\\jisaunqi.png"));//设置变量 setInputStream(inputStream); return SUCCESS; }
更多相关文章
- mybatisplus的坑 insert标签insert into select无参数问题的解决
- python起点网月票榜字体反爬案例
- NPM 和webpack 的基础使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- 安卓-编译过程简述
- 由安装Busybox到Android过程中想到的
- Android(安卓)资源(resource)学习小结
- 使用Content Provider
- android应用程序快速启动秘诀