整理之网络编程基础

基础之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类型的数据
    }
})
posted @ 2020-03-07 13:08  李振欣  阅读(171)  评论(0编辑  收藏  举报