【问题标题】:How can I retrieve the response from an http get request in Java WITHOUT BufferedReader如何在没有 BufferedReader 的情况下从 Java 中的 http get 请求中检索响应
【发布时间】:2020-04-29 21:48:44
【问题描述】:

我知道有成千上万的文章和问答可以教我如何用 Java 发送 HTTP 请求。但是它们都使用 BufferedReader 从服务器读取响应。

我不想使用 BufferedReader,因为在我的 android 项目中使用它时遇到了“OutOfMemoryError”。我不知道为什么在其他人成功时会发生这种情况,但是经过长时间的调试肯定是由BufferedReader引起的,我真的厌倦了这个问题。除了创建一个新的 BufferedReader 对象之外,还有什么方法可以检索响应? 我只是想发送一个最简单的get请求,得到提供HTML内容的响应,不考虑效率。

【问题讨论】:

  • 你也在使用 inputReader.readLine 吗?如果是这样,请尝试使用固定缓冲区大小进行读取: inputReader.read(char[] cbuf, int off, int len)
  • 它是一个 java web 应用程序吗?
  • don't want to use a BufferedReader, because I encountered an "OutOfMemoryError"。不,不要相信。您的错误来自其他原因。
  • BufferedReader inputReader 为什么称它为 inputReader?非常令人困惑,因为您还有新的 InputStreamReader.....
  • 你不考虑使用像 okhttp 或改造这样的包,它们在 http 连接上有一个包装器

标签: java android http get bufferedreader


【解决方案1】:

您可以为此使用 Volley。它快速、流畅且轻便。

在你的 build.gradle 文件中,添加这一行并编译:

implementation 'com.android.volley:volley:1.1.1'

制作一个网络单例

public class NetworkSingleton {
    private static NetworkSingleton instance;
    private RequestQueue requestQueue;
    private ImageLoader imageLoader;
    private static Context ctx;

    private NetworkSingleton(Context context) {
        ctx = context;
        requestQueue = getRequestQueue();

        imageLoader = new ImageLoader(requestQueue,
                new ImageLoader.ImageCache() {
                    private final LruCache<String, Bitmap>
                            cache = new LruCache<String, Bitmap>(20);

                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }

                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                });
    }

    public static synchronized NetworkSingleton getInstance(Context context) {
        if (instance == null) {
            instance = new NetworkSingleton(context);
        }
        return instance;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
        }
        return requestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return imageLoader;
    }
}

发出字符串请求:

StringRequest stringRequest = new StringRequest(Request.Method.GET, "URL to fetch",
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                       //This is executed after successful response to URL
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //If error occurs
                    }
                }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String>  params = new HashMap<String, String>();
                params.put("Authorization", "Add a header to request");

                return params;
            }
        };

        NetworkSingleton.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);

阅读更多关于凌空抽射的信息:

https://developer.android.com/training/volley

【讨论】:

  • 太好了。我真的厌倦了“这个流”,“那个流”...... Volley 看起来比 HttpURLConnection 容易得多。
  • 是的,确实如此。很干净。
【解决方案2】:

使用 OkHttp 进行高效的网络访问

什么是 OkHTTP? OkHTTP 是一个开源项目,旨在成为一个高效的 HTTP 客户端。

// avoid creating several instances, should be singleon
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
                     .url("https://www.vogella.com/index.html")
                     .build();

也可以添加参数

HttpUrl.Builder urlBuilder = HttpUrl.parse("https://api.github.help").newBuilder();
urlBuilder.addQueryParameter("v", "1.0");
urlBuilder.addQueryParameter("user", "vogella");
String url = urlBuilder.build().toString();

Request request = new Request.Builder()
                     .url(url)
                     .build();

来源https://www.vogella.com/tutorials/JavaLibrary-OkHttp/article.html

【讨论】:

  • 嗯,其实我昨天试过OKHTTP,很简单明了,但是我发现他们的文档大部分内容都是用Kotlin写的,我不是很熟悉,所以我更愿意选择Volley。不过谢谢你的回答!
【解决方案3】:

您可以使用InputStream
例如:

HttpURLConnection conn=(HttpURLConnection)(new URL(your URL).openConnection());
InputStream is=conn.getInputStream();
String str=new String(is.readAllBytes());
is.close();
return str;

或 Java 11 HttpClient API。
例如:

HttpClient client=HttpClient.newHttpClient();
HttpRequest request=HttpRequest.newBuilder().uri(new URI(your URL)).GET().build();
HttpResponse<String> response=client.send(request,BodyHandlers.ofString());
return response.body();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    相关资源
    最近更新 更多