【问题标题】:HttpUrlConnection redirection to other servlet is not happeningHttpUrlConnection 重定向到另一个 servlet 没有发生
【发布时间】:2015-03-31 05:39:39
【问题描述】:

我有以下代码将通过HttpUrlConnection调用服务器。

String response = HttpUtil.submitRequest(json.toJSONString(), "http://ipaddr:port/SessionMgr/validateSession?sessionId=_78998348uthjae3a&showLoginPage=true");

以上行将调用以下代码:

public static String submitRequest(String request, String **requestUrl**) {
    try {
        URL url = new URL(requestUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        OutputStream os = conn.getOutputStream();
        os.write(request.getBytes());
        os.flush();
        if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new RuntimeException("Failed : HTTP error code : "
                    + conn.getResponseCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));
        String output;
        StringBuffer sb = new StringBuffer();
        while ((output = br.readLine()) != null) {
            sb.append(output);
        }
        conn.disconnect();
        return sb.toString();

    } catch (MalformedURLException e) {
    } catch (IOException e) {
    }
    return "";
}

requestUrl 将转到下面的 servlet:

public class ValidateSessionServlet extends HttpServlet {
    String session = req.getParameter(sessionId);
    if (session == null) {
    // redirect to servlet which will display login page.
    response.setContentType("text/html");
            String actionUrl = getIpPortUrl(request)
                            + PropertyConfig.getInstance().getFromIdPConfig(globalStrings.getCheckSSOSession());
            out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"> \n");
            out.write("<html><head><body onload=\"document.forms[0].submit()\">\n");
            out.write("<form method=\"POST\" action=\"" + actionUrl + "\">\n");
            out.write("<input type=\"hidden\" name=\"locale\" value=\"" + locale + "\"/>\n");
            out.write("<input type=\"hidden\" name=\"Sessionrequest\" value=\"" + true + "\"/>\n");
            out.write("</form>\n</body>\n</html>\n");
     }
}

在上面的代码中,表单应该转到 actionUrl 中提到的 servlet,但它又会转到步骤 (1) 中的 servlet。

1) 我可以知道我们可以在步骤(3) 中制作上面的 html 表单以提交并重定向到 actionUrl 中的 servlet。

根据上面的代码,我正在总结要求。如果会话为空,我必须将用户重定向到登录页面并针对数据库进行验证,然后响应应该转到步骤(1),这可能吗?

【问题讨论】:

  • 有人能告诉我它是否有解决方案吗?
  • 您执行服务器端发布,您如何处理 POST 的输出?顺便说一句,我认为您正在采取危险的方式。如果你想在 HTTP 上进行类似 RPC 的调用,你也应该依赖 JSON 响应,混合模式(JSON 或 HTML)容易出错(可以做到,但会引发各种问题)。
  • 您是否正在对运营网站、自动登录等进行各种自动化操作?如果是这样,请考虑使用 selenium。

标签: java servlets httpurlconnection


【解决方案1】:

如果您希望您的HttpUrlConnection 支持重定向,您需要像这样设置您的HttpUrlConnection

...
conn.setRequestProperty("User-agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1");
conn.setInstanceFollowRedirects(true);
...

然后,如果您的服务器将您的请求重定向到其他地方,conn 将接收重定向的响应。

【讨论】:

    【解决方案2】:

    为了澄清,setInstanceFollowRedirects(true) 仅规定 HTTP 重定向是否应自动跟随 HttpURLConnection 实例。在您的特定情况下,您似乎希望根据 session 是否为 null (或基于您的特定应用程序逻辑的其他条件)重定向到 servlet。

    正确的(并且更能防止错误的解决方案)是检查HTTP 3xx 状态代码案例并手动处理重定向。这里以代码 sn-p 为例:

    if (responseStatusCode != HttpURLConnection.HTTP_OK) {
       switch(responseStatusCode){ 
          case HttpURLConnection.HTTP_MOVED_TEMP:
              // handle 302
          case HttpURLConnection.HTTP_MOVED_PERM:
              // handle 301
          case HttpURLConnection.HTTP_SEE_OTHER:                        
              String newUrl = conn.getHeaderField("Location");   // use redirect url from "Location" header field
              String cookies = conn.getHeaderField("Set-Cookie");       // if cookies are needed (i.e. for login)
              // manually redirect using a new connection 
              conn = (HttpURLConnection) new URL(newUrl).openConnection();
              conn.setRequestProperty("Cookie", cookies);
              conn.addRequestProperty("User-agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1"); 
          default:
              // handle default (other) case
       }
    }
    

    上面的代码与我用于应用的用户登录重定向的代码类似,而且我发现它很容易调试。 (一般情况下,我会手动处理 HTTP 状态代码案例,以避免出现错误。)

    最后,我建议使用良好的 JSON 库(例如 json.org)来解析您的响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-17
      • 2014-09-18
      • 1970-01-01
      • 2017-09-04
      • 2012-11-20
      • 2014-09-29
      • 1970-01-01
      相关资源
      最近更新 更多