一、使用背景
在项目中,我们经常会遇到需要多个系统数据对接的情况,有时还包括文件的传输。若仅仅是数据对接,且多个系统数据库在同一台数据库服务器上,我们可以使用Oracle的同义词来达到数据共享的目的。而更为常用的便是通过Web service技术来使得运行在不同服务器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可达到数据的相互交换的目的。
由于本人暂时还未接触过Web service技术,所以现通过HttpClient来实现类似Web service技术的数据交换接口。且本次还需要传输文件,经过实践最终也能成功传输,特此记录下来。
二、发送数据的服务端
1、写一个普通的Controller设定好访问路径;
2、设置此访问路径不受登录验证,即不需登录即可访问;
3、编写业务逻辑,为了安全可以双方协定一个服务调用码,只有服务调用码验证通过才能走正常业务逻辑。
代码示例:
/**
* 发送普通数据接口
* @param serviceCode 服务调用码
* @return 数据JSON对象
* @author zhoujin
* @date 2018-8-27
*/
@RequestMapping(value = "sendZbsmbList")
@ResponseBody
public JSONObject sendZbsmbList(String serviceCode){
JSONObject result = new JSONObject();
// 1.获取设定的服务调用码(从属性文件中读取)
String currentCode = Global.getConfig("zbsmbServiceCode");
if (currentCode.equals(serviceCode)) {
// 2.获取需要发送的数据列表
JSONArray jsonList = new JSONArray();
……
// 3.设定返回参数
result.put("success", true);
result.put("data", jsonList);
result.put("message", "数据请求成功!");
} else {
result.put("success", false);
result.put("message", "服务调用码错误!");
}
return result;
}
/**
* 发送文件数据接口
* @param fileId 文件ID
* @param serviceCode 服务调用码
* @return 文件内容
* @author zhoujin
* @throws IOException
* @date 2018-8-27
*/
@RequestMapping(value = "sendZbsmbStream")
public void sendZbsmbStream(String fileId, String serviceCode,HttpServletRequest request, HttpServletResponse response) throws IOException{
InputStream inStream = null;
// 0.获取HTTP输出流,数据将通过该输出流发送出去
ServletOutputStream outStream = response.getOutputStream();
response.setContentType("text/html;charset=utf-8");
// 1.获取设定的服务调用码(从属性文件中读取)
String currentCode = Global.getConfig("zbsmbServiceCode");
if (currentCode.equals(serviceCode)) {
// 2.获取该文件输入流
Map<String, String> map = new HashMap<String, String>();
map.put("id", fileId);
map.put("storagetype", shareFile.getStoragetype());
try {
inStream = fileService.downloadFile(map);
byte[] buf = new byte[1024 * 10];
int len = -1;
while((len = inStream.read(buf)) != -1){
outStream.write(buf, 0, len);
outStream.flush();
}
} catch (Exception e) {
response.setContentLength(-1);
e.printStackTrace();
} finally {
if (inStream != null) {
inStream.close();
}
if (outStream != null) {
outStream.close();
}
}
}else{
response.sendError(801, "服务调用码错误!"); // 自定义状态码
return null;
}
}
三、接收数据的客户端
1、获取HttpClient对象,设定访问路径以及参数设置;
2、执行发送请求,获取HttpResponse,并获取其中数据对象HttpEntity;
3、解析数据。
代码示例:
/* 部分导包情况 */
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/* Test-1 */
public static void getZbsmbList() throws Exception{
// 1.获取HttpClient对象
HttpClient httpclient = HttpClients.createDefault();
// 2.设定访问路径
HttpPost httppost = new HttpPost("http://localhost:9999/sendZbsmbList");
httppost.setHeader("Accept-Encoding", "identity");
// 3.设定参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("serviceCode", "csxt@zj_hqfusj")); // 参数名-数据
httppost.setEntity(new UrlEncodedFormEntity(nvps));
// 4.执行,发送请求
String str = "";
HttpResponse resultRep = httpclient.execute(httppost);
if (resultRep.getStatusLine().getStatusCode() == 200) {
// 5.获取传输的数据并解析
str = EntityUtils.toString(resultRep.getEntity());
if (StringUtils.isNotBlank(str)) {
……
}
} else {
System.out.println("服务访问失败!");
}
}
/* Test-2 */
public static void getZbsmbStream1() throws Exception{
// 1.获取HttpClient对象
HttpClient httpclient = HttpClients.createDefault();
// 2.设定访问路径
HttpPost httppost = new HttpPost("http://localhost:9999/sendZbsmbStream");
// 3.设定参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("fileId", "2ad4ec1fbf2048f3b12c089454cd901b")); // 参数名-数据
nvps.add(new BasicNameValuePair("serviceCode", "csxt@zj_hqfusj")); // 参数名-数据
httppost.setEntity(new UrlEncodedFormEntity(nvps));
// 4.执行,发送请求
HttpResponse resultRep = httpclient.execute(httppost);
int statusCode = resultRep.getStatusLine().getStatusCode();
if (statusCode == 200) {
// 5.获取传输的数据并解析
HttpEntity httpEntity = resultRep.getEntity();
// 6.将HTTP中返回实体转化为输入流
InputStream inStream = httpEntity.getContent();
FileOutputStream outStream = new FileOutputStream(new File("F:\\TestService\\testService.zip"));
byte[] buf = new byte[1024 * 10];
int len = -1;
while((len = inStream.read(buf)) != -1){
outStream.write(buf, 0, len);
}
inStream.close();
outStream.close();
System.out.println("文件输出结束!");
} else {
String result = EntityUtils.toString(resultRep.getEntity());
System.out.println(result.substring(result.indexOf("<h1>") + 4, result.indexOf("</h1>")));
}
}