【问题标题】:Https client 405 Method not allowedHttps 客户端 405 方法不允许
【发布时间】:2016-12-05 09:22:44
【问题描述】:

这是我的 Https 客户端

public String sendHttpsRequest(String httpsUrl, HttpMethod method, 
         String body, Map<String, String> headers) {

    String response = "";
    int responseCode = 0; 
    HttpsURLConnection conn = null;
    try {


        URL url = new URL(httpsUrl);
        conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod(method.toString());
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            conn.setRequestProperty(entry.getKey(), entry.getValue());
        }
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });


        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, new TrustManager[]{
                new javax.net.ssl.X509TrustManager() {

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }

                    @Override
                    public void checkClientTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }
                }
        }, null);
        conn.setSSLSocketFactory(context.getSocketFactory());


        String param = body;
        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.writeBytes(param);
        wr.flush();
        wr.close();
        responseCode = conn.getResponseCode();



        InputStream in = conn.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String line = "";

        while ((line = reader.readLine()) != null) {
            response += line;
        }
        reader.close();

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(conn != null) {
            conn.disconnect();
        }
    }

    return responseCode == 200?response:Integer.toString(responseCode);

}

但由于某种原因,当我尝试使用以下参数连接到https://httpbin.org/get 时,它给了我一个“405 方法不允许”。

    TreeMap<String, String> map = new TreeMap<>();
    map.put("Content-Type", "application/json");
    System.out.println(new HttpLiveTest().sendHttpsRequest("https://httpbin.org/get" , HttpMethod.GET, "", map));

我还尝试通过具有相同参数的 SoapUI 连接到它,并且它在那里工作。 我认为我从 Spring 使用的证书可能是问题,但我不知道如何解决该问题以及为什么要用 405 来回答?

使用 Wireshark 看包因为 TLS 不起作用

【问题讨论】:

  • setDoOutput(true) 可能会强制方法为 POST
  • java.net.ProtocolException: cannot write to a URLConnection if doOutput=false - call setDoOutput(true) 是我不设置为真时得到的结果

标签: java https request


【解决方案1】:

Arnaud 说:setDoOutput(true) 可能会强制方法为 POST

他说得对。

user7236363 写道: java.net.ProtocolException:如果 doOutput=false,则无法写入 URLConnection - 调用 setDoOutput(true) 是我在不将其设置为 true 时得到的结果

他也是对的。

大图: 您大部分时间想要做的是 HTTP GET 并且在 url 上传递参数 - 它不需要在 url 之后写入任何字节,因此根本不需要设置 Connection.setDoOutput(true),因此不需要当你想做一个 GET 时就去做。

在 Connection.setRequestProperty(String Key, String Value) 和 URL 本身之间,您应该拥有发出正确格式的 GET 请求所需的一切。

我遇到了一个非常相似的问题,其根源是我设置了 setDoOutput(true) 并且没有意识到它有一个我没有意识到的副作用(即将请求方法设置为 post)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2023-03-23
    • 2011-06-21
    • 2011-04-05
    相关资源
    最近更新 更多