Tomcat Servlet发起HTTPS请求外部Servlet出现404错误的解决求助
问题:Tomcat Servlet发起HTTPS请求外部Servlet返回404
在Tomcat的Servlet中执行HTTPS连接请求外部域名下的Servlet,返回ret = -11 - respCode = 404,但浏览器手动以GET方式携带参数访问该Servlet一切正常,代码中改用GET方式也依旧返回404。
请求代码
HttpsURLConnection hpcon = null; try { URL url = new URL(surl); hpcon = (HttpsURLConnection) url.openConnection(); hpcon.setRequestMethod("POST"); hpcon.setDoInput(true); hpcon.setDoOutput(true); hpcon.setUseCaches(false); hpcon.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); OutputStreamWriter wr = new OutputStreamWriter(hpcon.getOutputStream()); String params = "user=" + URLEncoder.encode(user, "UTF-8"); params += "&psswd=" + URLEncoder.encode(pssw, "UTF-8"); params += "&metodo=" + URLEncoder.encode(metodo, "UTF-8"); wr.write(params); wr.flush(); wr.close(); hpcon.connect(); int respCode = hpcon.getResponseCode(); if (respCode == 200) { BufferedReader br = new BufferedReader(new InputStreamReader(hpcon.getInputStream())); String response = ""; String output; while ((output = br.readLine()) != null) { response += output; } if (response.indexOf("-") > 0) { response = "-12"; System.out.println("ret = -12 - response = " + response); } br.close(); } else { ret = "-11"; System.out.println("ret = -11 - respCode = " + respCode); } } catch (Exception e) { e.printStackTrace(); ret = "-10"; System.out.println("ret = -10"); } finally { if (hpcon != null) { hpcon.disconnect(); } }
证书验证关闭代码
try { TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } }}; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } catch (Exception e) { e.printStackTrace(); }
解决建议
核对请求URL的准确性
打印代码中surl的完整值,和浏览器地址栏的URL逐字符对比:- 确认路径、端口(HTTPS默认443,是否被误写为其他端口)、上下文路径完全一致;
- 检查URL是否存在编码错误,比如特殊字符未转义导致路径解析异常。
补充浏览器默认请求头
浏览器发起请求时会携带User-Agent、Accept等默认头,部分服务器会依赖这些头进行路由匹配。在代码中添加这些头:hpcon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"); hpcon.setRequestProperty("Accept", "*/*");修正GET请求的参数拼接与配置
使用GET方式时,需确保:- 参数正确拼接到URL的查询字符串中,且完成URLEncode;
- 设置
setDoOutput(false),因为GET请求不需要输出流,否则服务器可能误判请求类型:String query = String.format("user=%s&psswd=%s&metodo=%s", URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(pssw, "UTF-8"), URLEncoder.encode(metodo, "UTF-8")); URL url = new URL(surl + "?" + query); hpcon = (HttpsURLConnection) url.openConnection(); hpcon.setRequestMethod("GET"); hpcon.setDoInput(true); hpcon.setDoOutput(false); // 关键:GET请求关闭输出流 hpcon.setUseCaches(false);
排查外部Servlet的路由限制
确认外部Servlet的配置:- 检查
web.xml或@WebServlet注解的url-pattern是否与请求路径匹配; - 确认Servlet是否限制了请求方法(比如仅允许GET,但代码中POST请求未被处理?不过你GET也返回404,此点优先级较低)。
- 检查
抓包对比请求差异
用抓包工具(如Wireshark、Fiddler)分别捕获浏览器和代码发起的请求,对比:- 请求URL的完整路径;
- 请求头的所有字段;
- 请求方法与参数传递方式,找出两者的差异点,定位问题根源。
内容的提问来源于stack exchange,提问作者stefano errani
相关产品推荐
相关产品推荐

