引言:最近在做客户的一个需求时,需要调用到客户的一个接口,根据客户所提供的接口文档,发现接口的请求参数为XML格式,响应结果也为XML。
一、流程概述
步骤 | 描述 |
---|---|
1 | 创建一个URL对象,指定目标URL地址 |
2 | 打开URL连接 |
3 | 设置请求的属性 |
4 | 将请求体的XML数据写入输出流 |
5 | 读取服务器返回的响应结果 |
6 | 关闭连接 |
二、代码实现
1、封装XML请求参数
编写一个公共方法,用于组装完整的xml请求代码块;虽然接口的输入参数复杂且为xml格式,但每次仅需要更改最中间的几个参数即可,所以可以通过字符串拼接,来实现对参数的修改
注意:以下输入的参数仅仅为了示例,具体参数根据自己需求而定
private String getXmlInfo(String param1,String param2) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
stringBuilder.append("<soapenv:Envelope xmlns:soapenv=\"http://xxx.xxx.org/soap/envelope/\" xmlns:eip=\"http://xxx.xxx.com.tempuri.org/\">");
stringBuilder.append(" <soapenv:Header/>");
stringBuilder.append(" <soapenv:Body>");
stringBuilder.append(" <eip:GetUserByToken>");
stringBuilder.append(" <参数一>"+param1+"</参数一>");
stringBuilder.append(" <参数二>"+param2+"</参数二>");
stringBuilder.append(" </eip:GetUserByToken>");
stringBuilder.append(" </soapenv:Body>");
stringBuilder.append("</soapenv:Envelope>");
return stringBuilder.toString();
}
2、调用接口
使用post直接请求,以下是调用接口的完整代码
// 可自己编写main方法测试
public static void main(String[] args) {
String loginName = creatPostAndTransData();
System.out.println(loginName);
}
public static String creatPostAndTransData() {
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
String loginName = "";
try {
// 设置URL地址
URL url = new URL(url);
// 打开连接
connection = (HttpURLConnection) url.openConnection();
// 设置请求方法
connection.setRequestMethod("POST");
// 设置请求头
connection.setRequestProperty("apikey", API_KEY);
connection.setRequestProperty("Accept", "application/xml");
connection.setRequestProperty("Content-Type", "text/xml");
// 允许输入输出流
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
// 构建请求体,将传来的接口参数组装为xml文本
String xmlInfo = getXmlInfo(param1XX,param2XX);
byte[] xmlInfoBytes = xmlInfo.getBytes(StandardCharsets.UTF_8);
//将请求体的XML数据写入输出流
OutputStream outputStream = connection.getOutputStream();
outputStream.write(xmlInfoBytes);
outputStream.close();
// 输入流,获取响应
int responseCode = connection.getResponseCode();
// 将字节流转为字符流InputStreamReader可以解决中文乱码的问题
InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8);
bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder resultStringBuilder = new StringBuilder();
String inputLine = "";
while ((inputLine = bufferedReader.readLine()) != null) {
resultStringBuilder.append(inputLine);
}
//服务端返回正常
if(responseCode == 200){
// 从返回的文本中,截取出我们需要的内容
int beginIndex = resultStringBuilder.indexOf("<GetUserByTokenResult>") + 22;
int endIndex = resultStringBuilder.lastIndexOf("</GetUserByTokenResult>");
loginName = resultStringBuilder.toString().substring(beginIndex,endIndex);
// 输出响应结果
log.error("Response Content: " + loginName);
}
} catch (Exception e) {
log.error(e,e.getMessage());
} finally {
//关闭连接,释放资源
if (connection!=null){
connection.disconnect();
}
if (bufferedReader!=null){
try {
bufferedReader.close();
} catch (IOException e) {
log.error("Failed to close stream due to "+e.getMessage(),e);
}
}
}
return loginName;
}
/**
* 将请求参数,组合为XML格式
**/
private static String getXmlInfo(String param1,String param2) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
stringBuilder.append("<soapenv:Envelope xmlns:soapenv=\"http://xxx.xxx.org/soap/envelope/\" xmlns:eip=\"http://xxx.xxx.com.tempuri.org/\">");
stringBuilder.append(" <soapenv:Header/>");
stringBuilder.append(" <soapenv:Body>");
stringBuilder.append(" <eip:GetUserByToken>");
stringBuilder.append(" <参数一>"+param1+"</参数一>");
stringBuilder.append(" <参数二>"+param2+"</参数二>");
stringBuilder.append(" </eip:GetUserByToken>");
stringBuilder.append(" </soapenv:Body>");
stringBuilder.append("</soapenv:Envelope>");
return stringBuilder.toString();
}
说明:
URL url = new URL(url);
中的url需指定为自己对应的请求地址connection.setRequestProperty("apikey", API_KEY);
这个属性根据需要来进行设置,apikey 是用来提供身份验证或授权的密钥,通常用于访问受保护的 API 或服务,将其设置为请求头的一部分,可以确保在向服务端发起请求时进行身份验证;在代码片段中,API_KEY 是一个变量。- 读取响应数据的字节流
InputStream
原本是按字节数组转为字符串方式,但会出现个别中文乱码的情况,将字节流转为字符流InputStreamReader
的方式可以成功解决。 - 我这个的返回数据只有被
<GetUserByTokenResult>
和</GetUserByTokenResult>
包裹的数据对我有用,且是个字符串,所以使用substring()截取出来就好了!你们也可以将XML格式字符串转为Document对象和Json对象这两种方式进行数据解析