基础之Http
GET请求字符串
//填写参数,构造连接
URL url = new URL("http://localhost:9102/get/text");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.setRequestMethod("GET");
connection.connect(); //连接服务器
//获取结果
int responseCode = urlConnection.getResponseCode();
if (responseCode == 200) {
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
String result = bufferedReader.readLine();
}
处理api27后不能使用明文请求链接的方法:
1.manifest文件中添加属性:android:usesSceartextTraffic="true"2.manifest文件中添加属性:android:networkSecurityConfig="@xml/network_security_config"
创建xml配置文件:network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">域名</domain> </domain-config> </domain-config> </network-security-config>
POST上传文本
InputStream is = null;
OutputStream os = null;
//填写参数,构造连接
URL url = new URL("http://localhost:9102/post/comment"); //链接可以带参数
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setConnectTimeout(10000);
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
connection.setRequestProperty("Accept", "application/json, text/plain, */*");
connection.setDoOutput(true); //打开上传开关
//上传内容
CommentItem item = new CommentItem("1234", "5678");
Gson gson = new Gson();
String jsonStr = gson.toJson(item);
byte[] bytes = jsonStr.getBytes();
connection.setRequestProperty("Content-Length", String.valueOf(bytes.length));
connection.connect(); //连接服务器
//流式上传
os = connection.getOutputStream();
os.write(bytes);
os.flush();
//获取上传结果
int responseCode = connection.getResponseCode();
new Logg().d(responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
is = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
new Logg().d(br.readLine());
}
基础之OkHttp
入门
//创建Client
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cache(new Cache(new File("cache"),18*1024*1024))
.readTimeout(5, TimeUnit.SECONDS)
.build();
//创建Request
Request request = new Request.Builder()
.url("http://www.baidu.com")
.get()
.build();
//封装Call
Call call = okHttpClient.newCall(request);//实际的Http请求,可以当做request和response连接的桥梁
//执行
//同步:
Response response = call.execute(); // 执行同步请求
response.body().toString(); //结果
//异步
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {
//在子线程中执行
}
});
框架之Retrofit
参考: https://blog.csdn.net/qq_36982160/article/details/94201257#URL_131
配置
导入依赖:
implementation 'com.squareup.retrofit2:retrofit:2.7.1'
基本操作流程
//定义网络请求接口
interface Api {
@GET("/p/fea5789f5d6d?utm_campaign") //链接的参数部分
fun getJson() : Call<ResponseBody>
}
//请求数据
val retrofit : Retrofit = Retrofit.Builder()
.baseUrl("https://www.jianshu.com/")
.build() //构建Retrofit对象
val api : Api = retrofit.create(Api::class.java) //构造请求对象
val task : Call<ResponseBody> = api.getJson() //实例化请求对象
task.enqueue(object : Callback<ResponseBody> { //请求数据
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {}
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
val data = response.body()?.string() //得到String类型的数据
//在UI线程中执行
}
})
URL操作
静态设置GET
//定义网络请求接口
interface Api {
@GET("/p/fea5789f5d6d?utm_campaign") //链接的参数部分
fun getJson() : Call<ResponseBody>
}
动态设置GET: 三种方法动态构造URL
interface Api {
//第一种方式: Path. 直接将参数插入到链接中
@GET("group/{id}/users")
fun fetchData(@Path("id") groupId: Int): Call<Response> // baseURL/group/{id}/users
//第二种方式: Query. 以键值对的形式插入到链接中
@GET("group")
fun fetchData(@Query("id") groupId: Int): Call<Response>// baseURL/group?id=groupId
//第二种方式: Path+Map. 先拼接Path再加入键值对
@GET("group/{id}")
fun fetchData(@Path("id") groupId: Int, @QueryMap params: Map<String, String>):
Call<Response> // baseURL/group/groupId?key=value
}
POST:
@POST("users/new")
val createUser(@Body User user) : Call<User> //直接以Bean类作为post的body
Header操作
静态设置
//单一参数
@Headers("Cache-Control: max-age=64000")
@GET("group/{id}/users")
fun fetchData(@Path("id") groupId: Int): Call<Response>
//多个参数
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("group/{id}/users")
fun fetchData(@Path("id") groupId: Int): Call<Response>
//当有多个请求头时,不会覆盖,而是同时发送
动态设置, 类似URL操作
//简单操作
@GET("group/{id}/users")
fun fetchData(@Header("Authorization") authorization: String): Call<Response>
//复杂操作
@GET("group/{id}/users")
fun fetchData(@HeaderMap params: Map<String, String>): Call<Response>
//当参数为null时会被忽略, 其他情况作为String传入
结果操作
1.使用转换器
默认情况下,Retrofit
只能反序列化OkHttp
中的ResponseBody
类型的返回值.但是通过转换器可以反序列化其他形式的返回值:
格式 | 库 |
---|---|
Jackson | com.squareup.retrofit2:converter-jackson |
Moshi | com.squareup.retrofit2:converter-moshi |
Protobuf | com.squareup.retrofit2:converter-protobuf |
Wire | com.squareup.retrofit2:converter-wire |
Simple XML | com.squareup.retrofit2:converter-simplexml |
Gson | com.squareup.retrofit2:converter-gson |
以Json格式为例
//添加Gson依赖 implementation 'com.squareup.retrofit2:converter-gson:2.7.1'
//添加Bean类
class DataBean(
var id: String,
var title: String,
var viewCount: Int,
var commentCount: Int,
var publishTime: String,
var userName: String,
var cover: String
)
//定义网络请求接口
interface Api {
@GET("/p/fea5789f5d6d?utm_campaign") //链接的参数部分
fun getJson() : Call<List<DataBean>>
}
//使用Bean类作为泛型请求数据
val retrofit : Retrofit = Retrofit.Builder()
.baseUrl("http://192.168.1.9:9102/")
.addConverterFactory(GsonConverterFactory.create()) //添加转换器
.build()
val api : Api = retrofit.create(Api::class.java)
val task : Call<<List<DataBean>> = api.getJsonResult()
task.enqueue(object : Callback<<List<DataBean>> {
override fun onFailure(call: Call<<List<DataBean>>, t: Throwable) {}
override fun onResponse(call: Call<<List<DataBean>>,
response: Response<<List<DataBean>>) {
val data = response.body()!!.data //得到Bean类型的数据
}
})