在Java中,要使用GET请求处理XML参数并返回结果,你可以使用HttpURLConnection
或更现代化的Apache HttpClient
库。下面是两个示例:
-
使用HttpURLConnection:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; public class XMLGetRequest { public static Document getXMLFromUrl(String url, String xmlData) { try { // 创建URL URL urlObject = new URL(url); // 创建连接 HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection(); // 设置为GET请求 connection.setRequestMethod("GET"); // 添加XML数据为查询参数 String encodedData = escapeXML(xmlData); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Length", Integer.toString(xmlData.length())); connection.getOutputStream().write(encodedData.getBytes()); // 设置无连接,防止阻塞 connection.setUseCaches(false); connection.setDoInput(true); connection.setDoOutput(true); // 读取响应 int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // 解析XML响应 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(new InputSource(new StringReader(response.toString()))); return doc; } else { throw new RuntimeException("Failed to connect with response code: " + responseCode); } } catch (Exception e) { e.printStackTrace(); return null; } } // 用于URL编码XML数据 private static String escapeXML(String xmlData) { try { return new String(xmlData.getBytes("UTF-8"), "UTF-8"); } catch (Exception e) { throw new RuntimeException("Error escaping XML data", e); } } }
-
使用
Apache HttpClient
:import org.apache.http.HttpResponse; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.w3c.dom.Document; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; public class XMLGetRequestWithApache { public static Document getXMLFromUrl(String url, String xmlData) { try { // 创建HttpClient实例 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建GET请求 HttpGet httpGet = new HttpGet(url); // 设置查询参数 StringEntity entity = new StringEntity(xmlData); entity.setContentType("application/x-www-form-urlencoded"); httpGet.setEntity(entity); // 执行请求 CloseableHttpResponse response = httpClient.execute(httpGet); // 确保请求成功 if (response.getStatusLine().getStatusCode() == 200) { String responseBody = EntityUtils.toString(response.getEntity()); // 解析XML响应 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(new InputSource(new StringReader(responseBody))); return doc; } else { throw new RuntimeException("Failed to connect with response code: " + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); return null; } finally { // 关闭连接 try { if (response != null) { response.close(); } } catch (IOException ioex) { ioex.printStackTrace(); } } } }
如果你想返回的是字符串类型,你可以直接从HTTP响应中读取并解析XML。以下是两个示例中的修改版本,返回结果是一个字符串:
-
使用HttpURLConnection,返回字符串:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class XMLGetRequest { public static String getXMLFromUrl(String url, String xmlData) { try { // 创建URL URL urlObject = new URL(url); // 创建连接 HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection(); // 设置为GET请求 connection.setRequestMethod("GET"); // 添加XML数据为查询参数 String encodedData = escapeXML(xmlData); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Length", Integer.toString(xmlData.length())); connection.getOutputStream().write(encodedData.getBytes()); // 设置无连接,防止阻塞 connection.setUseCaches(false); connection.setDoInput(true); connection.setDoOutput(true); // 读取响应 int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return response.toString(); } else { throw new RuntimeException("Failed to connect with response code: " + responseCode); } } catch (Exception e) { e.printStackTrace(); return null; } } // 用于URL编码XML数据 private static String escapeXML(String xmlData) { // (代码不变,此处省略) } }
-
使用
Apache HttpClient,返回字符串
:import org.apache.http.HttpResponse; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; public class XMLGetRequestWithApache { public static String getXMLFromUrl(String url, String xmlData) { try { // 创建HttpClient实例 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建GET请求 HttpGet httpGet = new HttpGet(url); // 设置查询参数 StringEntity entity = new StringEntity(xmlData); entity.setContentType("application/x-www-form-urlencoded"); httpGet.setEntity(entity); // 执行请求 CloseableHttpResponse response = httpClient.execute(httpGet); // 确保请求成功 if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity()); } else { throw new RuntimeException("Failed to connect with response code: " + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); return null; } finally { // 关闭连接 try { if (response != null) { response.close(); } } catch (IOException ioex) { ioex.printStackTrace(); } } } }
这两个示例现在都会返回一个字符串类型的XML响应内容。如果需要解析XML,你可以使用
javax.xml.parsers
包的DocumentBuilder
或相关的XML解析库,如DOM4J
,JAXB
,Jackson-dataformat-xml
等。
在使用Apache HttpClient
时,HttpGet
对象不能直接设置实体(entity),因为HttpGet
是用于发送GET请求的,并不携带请求体。你应该用HttpGet
构建URL并传递 parameters,而不是设置实体。以下是改进后的版本: -
使用
HttpUrl encodedGet
方法来构造GET请求:import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class XMLGetRequestWithApache { public static String getXMLFromUrl(String url, String xmlData) { try { // 创建HttpClient实例 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建包含查询参数的GET请求 HttpGet httpGet = new HttpGet(url + "?" + xmlData); // 执行请求 CloseableHttpResponse response = httpClient.execute(httpGet); // 确保请求成功 if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity()); } else { throw new RuntimeException("Failed to connect with response code: " + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); return null; } finally { // 关闭连接 try { if (response != null) { response.close(); } } catch (IOException ioex) { ioex.printStackTrace(); } } } }
在这个版本中,我们在URL上添加了查询参数,形式为
url?xmlData
,而不是使用setEntity
。请注意,这种方式可能不适用于非常大的查询参数,因为URL长度有一定的限制。
以上代码报错:java.lang.IllegalArgumentException: Illegal character in query at index 24: http://....?<result>...</result>字符编码问题或者某些字符需要URL编码。在HTTP查询参数中,有一些字符(如空格、特殊字符等)需要转换为它们的URL编码形式,如
%20
代表空格。在上面的代码中,添加查询参数时没有进行编码。让我们对
xmlData
使用URLEncoder
进行编码,然后再构造HttpGet
。以下是修改后的代码: -
使用URLEncoder进行编码
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; public class XMLGetRequestWithApache { public static String getXMLFromUrl(String url, String xmlData) { try { // 创建编码后的查询参数 String encodedData = URLEncoder.encode(xmlData, StandardCharsets.UTF_8).replace("+", "%20"); // 创建HttpClient实例 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建带有编码查询参数的GET请求 HttpGet httpGet = new HttpGet(url + "?" + encodedData); // 执行请求 CloseableHttpResponse response = httpClient.execute(httpGet); // 确保请求成功 if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity()); } else { throw new RuntimeException("Failed to connect with response code: " + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); return null; } finally { // 关闭连接 try { if (response != null) { response.close(); } } catch (IOException ioex) { ioex.printStackTrace(); } } } }
现在,
xmlData
字符串将被正确编码,并用于构造GET请求的URL。如果问题仍未解决,可能是有字符在URL编码中是不被接受的,可能需要根据服务器的要求进一步调整。如果你确认URL编码后返回的结果仍然有错误,可能是因为服务器端接收到的编码并不支持或期望的不是标准的URL编码格式。 -
使用post请求
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import java.io.IOException; public class XMLPostRequestWithApache { public static String postXMLToUrl(String url, String xmlData) { try { // 创建HttpClient实例 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建POST请求 HttpPost httpPost = new HttpPost(url); // 将请求体设为XML数据 httpPost.setEntity(new StringEntity(xmlData, StandardCharsets.UTF_8)); // 设置适当的请求头,视情况可能需要添加如Content-Type等 httpPost.setHeader("Content-Type", "text/xml"); // 发送请求并获取响应 CloseableHttpResponse response = httpClient.execute(httpPost); // 确保请求成功 if (response.getStatusLine().getStatusCode() == 200) { String responseBody = EntityUtils.toString(response.getEntity()); return responseBody; } else { throw new RuntimeException("Failed to connect with response code: " + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); return null; } finally { // 关闭连接 try { if (response != null) { response.close(); } } catch (IOException ioex) { ioex.printStackTrace(); } } } }
在这个示例中,我使用了
HttpPost
发布POST请求,设置了请求体(StringEntity
),并管理了请求头。你需要确保Content-Type符合服务器的要求,如这里是text/xml
。如果你知道服务器端需要的HTTP方法(如PATCH
、PUT
等),请相应地替换HttpPost
。