【问题标题】:Java HttpURLConnection status code 302Java HttpURLConnection 状态码 302
【发布时间】:2016-09-27 19:09:23
【问题描述】:

我试图让这个代码块运行,但我一直收到 302。我试图展示代码的流程。我就是不知道怎么回事。

import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Base64;

public class AuthenticateLoginLogoutExample {


public static void main(String[] args) throws Exception {
    new AuthenticateLoginLogoutExample().authenticateLoginLogoutExample(
                    "http://" + Constants.HOST + "/qcbin",
                    Constants.DOMAIN,
                    Constants.PROJECT,
                    Constants.USERNAME,
                    Constants.PASSWORD);
}

public void authenticateLoginLogoutExample(final String serverUrl,
      final String domain, final String project, String username,
      String password) throws Exception {

    RestConnector con =
            RestConnector.getInstance().init(
                    new HashMap<String, String>(),
                    serverUrl,
                    domain,
                    project);

    AuthenticateLoginLogoutExample example =
        new AuthenticateLoginLogoutExample();

    //if we're authenticated we'll get a null, otherwise a URL where we should login at (we're not logged in, so we'll get a URL).

当它从 isAuthenticated() 方法开始时就是下一行。

    String authenticationPoint = example.isAuthenticated();
    Assert.assertTrue("response from isAuthenticated means we're authenticated. that can't be.", authenticationPoint != null);

    //do a bunch of other stuff
}

所以我们进入isAuthenticated方法:

public String isAuthenticated() throws Exception {

    String isAuthenticateUrl = con.buildUrl("rest/is-authenticated");
    String ret;

然后在下一行尝试获得响应。 con.httpGet

    Response response = con.httpGet(isAuthenticateUrl, null, null);
    int responseCode = response.getStatusCode();

    //if already authenticated
    if (responseCode == HttpURLConnection.HTTP_OK) {

        ret = null;
    }

    //if not authenticated - get the address where to authenticate
    // via WWW-Authenticate
    else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {

        Iterable<String> authenticationHeader =
                response.getResponseHeaders().get("WWW-Authenticate");

        String newUrl =
            authenticationHeader.iterator().next().split("=")[1];
        newUrl = newUrl.replace("\"", "");
        newUrl += "/authenticate";
        ret = newUrl;
    }

    //Not ok, not unauthorized. An error, such as 404, or 500
    else {

        throw response.getFailure();
    }

    return ret;
}

这让我们跳到另一个类并进入这个方法:

public Response httpGet(String url, String queryString, Map<String,
       String> headers)throws Exception {

    return doHttp("GET", url, queryString, null, headers, cookies);
}

doHttp 将我们带到这里。 type = "GET", url = "http://SERVER/qcbin/rest/is-authenticated",其余均为空。

private Response doHttp(
        String type,
        String url,
        String queryString,
        byte[] data,
        Map<String, String> headers,
        Map<String, String> cookies) throws Exception {

    if ((queryString != null) && !queryString.isEmpty()) {

        url += "?" + queryString;
    }

    HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();

    con.setRequestMethod(type);
    String cookieString = getCookieString();

    prepareHttpRequest(con, headers, data, cookieString);

下一行的这个 con.connect() 永远不会连接。

    con.connect();
    Response ret = retrieveHtmlResponse(con);

    updateCookies(ret);

    return ret;
}

prepareHttpRequest 代码:

private void prepareHttpRequest(
        HttpURLConnection con,
        Map<String, String> headers,
        byte[] bytes,
        String cookieString) throws IOException {

    String contentType = null;

    //attach cookie information if such exists
    if ((cookieString != null) && !cookieString.isEmpty()) {

        con.setRequestProperty("Cookie", cookieString);
    }

    //send data from headers
    if (headers != null) {

        //Skip the content-type header - should only be sent
        //if you actually have any content to send. see below.
        contentType = headers.remove("Content-Type");

        Iterator<Entry<String, String>>
            headersIterator = headers.entrySet().iterator();
        while (headersIterator.hasNext()) {
            Entry<String, String> header = headersIterator.next();
            con.setRequestProperty(header.getKey(), header.getValue());
        }
    }

    // If there's data to attach to the request, it's handled here.
    // Note that if data exists, we take into account previously removed
    // content-type.
    if ((bytes != null) && (bytes.length > 0)) {

        con.setDoOutput(true);

        //warning: if you add content-type header then you MUST send
        // information or receive error.
        //so only do so if you're writing information...
        if (contentType != null) {
            con.setRequestProperty("Content-Type", contentType);
        }

        OutputStream out = con.getOutputStream();
        out.write(bytes);
        out.flush();
        out.close();
    }
}

还有 getCookieString 方法:

public String getCookieString() {

    StringBuilder sb = new StringBuilder();

    if (!cookies.isEmpty()) {

        Set<Entry<String, String>> cookieEntries =
            cookies.entrySet();
        for (Entry<String, String> entry : cookieEntries) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append(";");
        }
    }

    String ret = sb.toString();

    return ret;
}

有人知道出了什么问题吗?我不知道为什么它总是返回 302。

编辑:按要求添加了 chrome 开发者图片。

【问题讨论】:

标签: java rest alm


【解决方案1】:

我没有关注你的整个代码,但是 http 302 意味着重定向 https://en.wikipedia.org/wiki/HTTP_302

取决于重定向的类型,这可能会顺利或不顺利。例如,前几天我遇到了 http 到 https 的重定向,我必须手动检查位置标头来解决它。

我要做的是首先检查浏览器中的标头,在 Chrome 中转到开发人员工具、网络并检查响应标头(屏幕截图)。您应该会在 302 响应中看到 Location Header,其中包含您应该遵循的新 URL。

【讨论】:

  • 当我手动输入 URL 并访问该站点时,我看到我多次收到安全警告对话框。知道如何以编程方式处理这些问题吗?
  • 当您说“手动”时,您的意思是使用浏览器,对吗?如果您的 Java 代码得到 302,它并不担心您的浏览器正在发现的安全问题。
  • 如果您可以将这些屏幕截图添加到您的问题中,将会很有帮助。但我首先要做的是在浏览器中执行请求,并检查其中的标头。我已经编辑了我的答案,请查看。
  • 好吧,我终于成功上传了截图。它在我原始帖子的底部上方。我可以在其中一个标题中看到正在传递 cookie 信息。底部的长拉伸。我该怎么做?
  • 好的,如果你看到你的截图,你最初请求的是一个 http 请求,然后你被重定向到一个 https 请求。 (请参阅响应标头部分中的位置标头)
【解决方案2】:

302 表示那里有一个页面,但您确实想要一个不同的页面(或者您想要这个页面,然后是另一个页面)。如果您查看从服务器返回的标头,当它为您提供 302 时,您可能会找到一个“Location:”标头,告诉您接下来要查询的位置,您将不得不编写另一个事务。

浏览器解释 302 响应并自动重定向到“Location:”标头中指定的 URL。

【讨论】:

    猜你喜欢
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 1970-01-01
    • 2011-09-12
    • 2014-05-02
    • 2018-03-28
    • 2014-07-23
    相关资源
    最近更新 更多