向WebService发送XML请求时遇500错误,求解决思路
问题描述
调用Workday的WebService接口发送XML请求时收到500内部服务器错误,无法自行排查,请求提供排查思路和解决方案。
提供的实现代码
String wsURL = "https://wd2-impl-services1.workday.com/ccx/service/Payteam/v10.2?wsdl"; URL url = null; URLConnection connection = null; HttpURLConnection httpConn = null; String responseString = null; String outputString=""; OutputStream out = null; InputStreamReader isr = null; BufferedReader in = null; String xmlInput = "XMLdocument"; try { url = new URL(wsURL); connection = url.openConnection(); httpConn = (HttpURLConnection) connection; byte[] buffer = new byte[xmlInput.length()]; buffer = xmlInput.getBytes(); String SOAPAction = ""; //Set the appropriate HTTP parameters\Properties. httpConn.setRequestProperty("Content-Length", String.valueOf(buffer.length)); httpConn.setRequestProperty("Content-Type","text/xml; charset-utf-8"); httpConn.setRequestProperty("Username","username"); httpConn.setRequestProperty("Password", "password"); httpConn.setRequestProperty("SOAPAction",SOAPAction); httpConn.setRequestMethod("POST"); httpConn.setDoOutput(true); httpConn.setDoInput(true); out = httpConn.getOutputStream(); out.write(buffer); out.close(); //Read Response isr = new InputStreamReader(httpConn.getInputStream()); in = new BufferedReader(isr); while ((responseString = in.readLine()) != null) { outputString = outputString + responseString; } System.out.println(outputString); System.out.println(""); Document document = parseXmlFile(outputString); } catch (Exception e) { e.printStackTrace(); } private static Document parseXmlFile(String in) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputSource is = new InputSource(new StringReader(in)); return db.parse(is); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } catch (SAXException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } }
排查思路及解决方案
一、优先获取服务器详细错误信息
500错误的核心是服务器内部处理失败,但通常会返回错误详情(如SOAP Fault),当前代码直接调用getInputStream()会抛出异常,无法获取错误内容。修改异常处理逻辑,读取错误流:
catch (Exception e) { e.printStackTrace(); // 新增:读取错误响应 if (httpConn != null && httpConn.getResponseCode() >= 400) { BufferedReader errorReader = new BufferedReader(new InputStreamReader(httpConn.getErrorStream())); String errorLine; String errorOutput = ""; while ((errorLine = errorReader.readLine()) != null) { errorOutput += errorLine; } System.out.println("服务器错误响应:" + errorOutput); errorReader.close(); } }
拿到错误响应后,就能明确是认证、XML格式还是其他具体问题。
二、修正认证方式
Workday WebService通常采用Basic认证,而非直接传递Username和Password请求头。正确做法是将用户名密码用Base64编码后放在Authorization头:
// 替换原有的Username和Password头设置 String auth = "username" + ":" + "password"; byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8)); String authHeader = "Basic " + new String(encodedAuth); httpConn.setRequestProperty("Authorization", authHeader);
注意:需要导入java.util.Base64和java.nio.charset.StandardCharsets。
三、修正请求头错误
- Content-Type拼写错误:原代码中
charset-utf-8缺少等号,应为charset=utf-8:
httpConn.setRequestProperty("Content-Type","text/xml; charset=utf-8");
- SOAPAction头不能为空:SOAP 1.1要求该头对应WSDL中操作的
soap:action值,从WSDL文档中找到目标操作的SOAPAction(例如"urn:com.workday/bsvc/Payteam/v10.2/YourOperation"),填入SOAPAction变量。
四、修正服务地址
原代码使用带?wsdl的地址,这是获取WSDL文档的地址,而非实际调用的服务端点,应去掉?wsdl:
String wsURL = "https://wd2-impl-services1.workday.com/ccx/service/Payteam/v10.2";
五、确保XML请求合法性
- 确认
xmlInput是完整的SOAP信封格式,包含正确的命名空间、根元素,符合WSDL定义的请求结构。 - 替换硬编码的"XMLdocument"为实际的SOAP请求内容,可通过SOAP UI等工具生成合法请求后再代入代码。
六、修正编码问题
原代码xmlInput.getBytes()使用平台默认编码,可能导致编码不一致,应指定UTF-8:
byte[] buffer = xmlInput.getBytes(StandardCharsets.UTF_8); // 同时修正Content-Length计算,确保和实际发送的字节数一致 httpConn.setRequestProperty("Content-Length", String.valueOf(buffer.length));
内容的提问来源于stack exchange,提问作者user22686339
相关产品推荐
相关产品推荐

