okhttp同步/异步

public class MainActivity extends AppCompatActivity {
    private OkHttpClient okHttpClient;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        okHttpClient = App.okHttpClient();
    }
    //同步的get
    public void get(View view) {
        //request 设置url
        final Request request= new Request.Builder()
                .url("http://www.baidu.com")
                .build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //通过newCall方法将request转换成call ,如果用execute()是同步执行
                    Response execute = okHttpClient.newCall(request).execute();
                    if (execute.isSuccessful()){
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this,"get成功",Toast.LENGTH_SHORT).show();
                            }
                        });
                    }else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this,"get失败",Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    //异步get,所以的回调方法里面都是分线程.不能更新ui
    public void getAsync(View view) {
        final Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,"异步get失败",Toast.LENGTH_SHORT).show();
                    }
                });
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()){
                    String json = response.body().toString();
                    //Gson解析
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "get成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                }else {
                    //Gson解析
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "getshibai", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        });
    }
    //Post异步请求
    public void postAsync(View view) {
        FormBody formBody = new FormBody.Builder()
                .add("type", "yuantong")
                .add("postid", "1111111")
                .build();
        Request request = new Request.Builder()
                .url(" http://www.kuaidi100.com/query")
                .post(formBody)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,"异步get失败",Toast.LENGTH_SHORT).show();
                    }
                });
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()){
                    String json = response.body().toString();
                    //Gson解析
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "post成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                }else {
                    //Gson解析
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "getshibai", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        });
            }
        }
Myapp:
public class App extends Application {

    private static OkHttpClient okHttpClient;

    @Override
    public void onCreate() {
        super.onCreate();
        //建议一个app只有一个OkHttpClient实例
        okHttpClient = new OkHttpClient();
        okHttpClient = okHttpClient.newBuilder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .addInterceptor(new MyLogInterceptor())
                .build();
    }

    public static OkHttpClient okHttpClient() {
        return okHttpClient;
    }
    //拦截器,可以修改header,可以通过拦截器打印日志
    private class MyLogInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
         Request request = chain.request().newBuilder()
                    .header("shenfen", "chinesse")
                    .build();
            HttpUrl url = request.url();
            String httpUrl = url.url().toString();
            Log.e("TAG", "============" + httpUrl);
            Response response = chain.proceed(request);
            int code = response.code();
            Log.e("TAG", "============response.code() == " + code);
            return response;
    }
}
}

<think>我们有两个引用,其中引用[1]和引用[2]都提供了发送application/json请求的示例代码。用户要求一个具体的示例代码,因此我们可以结合这两个引用来提供一个更完整的示例。 注意点: 1. 使用OkHttp发送POST请求,请求体为JSON字符串。 2. 设置请求头Content-Type为application/json。 3. 使用RequestBody.create()方法创建请求体。 4. 使用OkHttpClient的newCall()方法发送请求并获取响应。 我们将提供一个同步请求的示例,并包括异常处理和资源释放。 示例代码: ```java import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import java.io.IOException; public class OkHttpJsonExample { // 定义JSON媒体类型 private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); public static void main(String[] args) { String url = "https://api.example.com/endpoint"; // 替换为实际URL String json = "{\"key1\":\"value1\", \"key2\":\"value2\"}"; // JSON字符串 try { String response = postJson(url, json); System.out.println(response); } catch (IOException e) { e.printStackTrace(); } } public static String postJson(String url, String json) throws IOException { OkHttpClient client = new OkHttpClient(); // 创建请求体 RequestBody body = RequestBody.create(json, JSON); // 注意:在OkHttp 3.12.x及之前版本,使用create方法 // 在OkHttp 4.x及以上版本,RequestBody.create方法有所变化,推荐使用: // RequestBody body = RequestBody.create(json, JSON); // 构建请求 Request request = new Request.Builder() .url(url) .post(body) .build(); // 发送请求并处理响应 try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) { throw new IOException("Unexpected code " + response); } return response.body().string(); } } } ``` 注意:上述代码中,我们使用了try-with-resources来确保Response资源被正确关闭。另外,我们检查了响应是否成功(状态码在200-299之间)。 但是,请注意OkHttp的版本差异: - 在OkHttp 3.12.x及之前版本,`RequestBody.create`方法有两个参数:第一个是字符串,第二个是MediaType。 - 在OkHttp 4.x及以上版本,`RequestBody.create`方法被标记为过时,推荐使用`RequestBody.create(String, MediaType)`的静态方法,但注意参数顺序:先传入字符串,再传入MediaType。或者,也可以使用`RequestBody.create`的重载方法(如传入字节数组)。但是,对于字符串,我们仍然可以使用`RequestBody.create(json, JSON)`。 如果使用的是OkHttp 4.x,并且遇到方法过时的情况,可以改用: ```java RequestBody body = RequestBody.create(json, JSON); ``` 因为即使标记为过时,这个方法在4.x中仍然可用。 另外,如果希望添加请求头,可以在构建请求时添加,例如: ```java Request request = new Request.Builder() .url(url) .addHeader("Content-Type", "application/json") .addHeader("Authorization", "Bearer token") .post(body) .build(); ``` 但是,通常我们已经在RequestBody中指定了MediaType,所以Content-Type头会自动设置为"application/json; charset=utf-8"。如果额外设置Content-Type头,可能会覆盖掉默认值,但这里设置的值和默认值一致,所以也可以不设置。 根据引用[1],我们还可以在构建请求时添加多个请求头。如果需要,可以按照引用[1]中的方式构建Headers。 现在,我们提供一个更通用的方法,可以添加自定义请求头(参考引用[1]): ```java import okhttp3.Headers; import java.util.Map; public static String postJsonWithHeaders(String url, Map<String, String> headers, String json) throws IOException { OkHttpClient client = new OkHttpClient(); RequestBody body = RequestBody.create(json, JSON); // 构建请求头 Headers.Builder headersBuilder = new Headers.Builder(); if (headers != null) { for (Map.Entry<String, String> entry : headers.entrySet()) { headersBuilder.add(entry.getKey(), entry.getValue()); } } Request request = new Request.Builder() .url(url) .headers(headersBuilder.build()) .post(body) .build(); try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) { throw new IOException("Unexpected code " + response); } return response.body().string(); } } ``` 这样,用户就可以传入自定义的请求头了。 最后,我们需要注意:`response.body().string()`只能调用一次,因为它会消耗整个响应流,再次调用会抛出异常。 因此,我们返回字符串后,调用者可以按需使用。 如果用户需要异步请求,可以参考之前的回答中的异步示例。 现在,我们根据用户的问题,提供发送application/json请求的代码示例,并生成相关问题。</think>### OKHTTP 发送 application/json 请求的完整示例 以下是使用 OkHttp 发送 JSON 格式 POST 请求的完整代码示例(基于引用[1][2]的最佳实践): ```java import okhttp3.*; import java.io.IOException; import java.util.Map; public class OkHttpJsonExample { // 发送 JSON POST 请求的通用方法 public static String postJson(String url, Map<String, String> headers, String jsonBody) throws IOException { // 1. 创建 OkHttpClient 实例 OkHttpClient client = new OkHttpClient(); // 2. 创建 JSON 媒体类型 MediaType JSON = MediaType.parse("application/json; charset=utf-8"); // 3. 构建请求体 RequestBody body = RequestBody.create(jsonBody, JSON); // 引用[2] // 4. 构建请求头 Headers.Builder headersBuilder = new Headers.Builder(); for (Map.Entry<String, String> entry : headers.entrySet()) { headersBuilder.add(entry.getKey(), entry.getValue()); } // 5. 创建请求对象 Request request = new Request.Builder() .url(url) .headers(headersBuilder.build()) .post(body) // 设置 POST 请求 .build(); // 引用[1] // 6. 发送请求并处理响应 try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) { throw new IOException("请求失败: " + response.code()); } return response.body().string(); } } // 使用示例 public static void main(String[] args) { String url = "https://api.example.com/data"; String jsonPayload = "{\"username\":\"test\", \"password\":\"123456\"}"; // 设置请求头 Map<String, String> headers = Map.of( "Content-Type", "application/json", "Authorization", "Bearer your_token_here" ); try { String response = postJson(url, headers, jsonPayload); System.out.println("响应内容: " + response); } catch (IOException e) { e.printStackTrace(); } } } ``` ### 关键点说明 1. **媒体类型设置** `MediaType.parse("application/json; charset=utf-8")` 确保正确设置 JSON 格式和编码 2. **请求头管理** 使用 `Headers.Builder` 动态添加请求头(如认证令牌等) 3. **资源自动释放** `try-with-resources` 语法确保响应资源自动关闭 4. **错误处理** `response.isSuccessful()` 检查 HTTP 状态码(200-299) 5. **JSON 格式要求** 请求体必须是有效的 JSON 字符串,如: ```java // 使用 JSON 库生成更安全 String json = "{\"key1\":\"value1\", \"key2\":42}"; ``` ### 常见问题解决 1. **字符编码问题** 确保 JSON 字符串使用 UTF-8 编码: ```java String json = new String("{\"name\":\"中文\"}".getBytes(), StandardCharsets.UTF_8); ``` 2. **大 JSON 处理** 使用流式处理避免内存溢出: ```java RequestBody body = RequestBody.create( Files.asByteSource(new File("large.json")), JSON ); ``` 3. **异步请求示例** ```java client.newCall(request).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { // 在后台线程处理响应 } @Override public void onFailure(Call call, IOException e) { // 错误处理 } }); ``` > 注意:`response.body().string()` 只能调用一次,多次调用会抛出异常[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值