项目中有这样一个场景:web工程接收到外部数据后,需要转发给biz工程进行处理,然后biz将处理结果数据返回给web工程。为什么要这么做呢?是因为蛋疼的网络权限控制,只有web工程能够跟外部打交道,那么问题来了,这种交互模式如何处理?
这里就使用到了HttpURLConnection对象,直接看如下方法吧,在web工程中使用如下:
public static String getResponseMessage(String resMsgUrl, String requestXmlData) throws IOException
{
// 向biz的接口发用户的上行消息,把requestXmlData发给biz工程的接口,这里的resMsgUrl就是biz工程提供的url
URL url = new URL(resMsgUrl);
//建立连接
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//设置是否向HttpURLConnection输出,因为这个是post请求,参数放在http正文内,因此需要设置为true,默认为false
httpURLConnection.setDoOutput(true);
//设置是否从HttpURLConnection读入,默认为true
httpURLConnection.setDoInput(true);
//设置请求方法
httpURLConnection.setRequestMethod("POST");
//设置连接超时时间
httpURLConnection.setConnectTimeout(5000);
//设置读取超时时间
httpURLConnection.setReadTimeout(5000);
//对请求的正文使用urlencode进行编码
httpURLConnection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
//一定是上面的参数设置完了之后才进行connection连接
httpURLConnection.connect();
//使用BufferedWriter对象进行参数写入到正文
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8"));
if(StringUtils.isNotEmpty(requestXmlData)){
out.write(requestXmlData);
}
out.flush();
out.close();
int code = httpURLConnection.getResponseCode();
String message = httpURLConnection.getResponseMessage();
logger.info("%%%name:" + httpURLConnection.getHeaderField("name"));
// 连接成功后,从biz的接口读取返回的message
if (code == 200 || message.equalsIgnoreCase("ok"))
{
InputStream inputStream = httpURLConnection.getInputStream();
String resonpseMessage = readBytesFromStream(inputStream);
inputStream.close();
httpURLConnection.disconnect();
return resonpseMessage;
}
httpURLConnection.disconnect();
return "";
}
biz提供接口,先从request对象中读出web的请求参数,然后根据参数在数据库中找到欲返回的信息,然后通过BufferedWriter对象写入到response中,代码如下:
@RequestMapping(value="res_message.xhtml",method = RequestMethod.POST)
public void resMessage(HttpServletRequest request, HttpServletResponse response) throws IOException{
String requestXmlData = Util.getRequestXmlData(request);
String resopnseXmlData = messageService.getResponseXml(requestXmlData);
response.setCharacterEncoding("UTF-8");
logger.info("&&&&&&&resopnseXmlData:"+resopnseXmlData);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8"));
out.write(resopnseXmlData);
out.flush();
out.close();
}
二者的交互就完成了,值得注意的是,上述两个方法中都涉及到了从request或InputStream中读取数据,这里有两种模式:
1、按行读取,例如:
public static String getRequestXmlData(HttpServletRequest request) throws IOException
{
request.setCharacterEncoding("UTF-8");
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream(), "UTF-8"));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null)
{
sb.append(line);
}
String recievestr = sb.toString();
return recievestr;
}
public static String readBytesFromStream(InputStream inputStream) throws IOException
{
String responseStr = "";
String totalResponseStr = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((responseStr = reader.readLine()) != null)
{
totalResponseStr += responseStr + "\n";
}
return totalResponseStr;
}
2、按规定字符串长度读取
逐字节读取:
public static String getRequestXmlData(HttpServletRequest request) throws IOException {
ServletInputStream sis = request.getInputStream();
int size = request.getContentLength()==-1?0:request.getContentLength();
byte[] buffer = new byte[size];
byte[] xmldataByte = new byte[size];
int count = 0;
int rbyte = 0;
while (count < size) {
rbyte = sis.read(buffer);
for (int i = 0; i < rbyte; i++) {
xmldataByte[count + i] = buffer[i];
}
count += rbyte;
}
return new String(xmldataByte, "UTF-8");
}
这里很容易出现乱码,因为每次按长度进行读取,如果刚好一个汉字被截断,就会出现乱码,因此不建议这么使用。
public static String readBytesFromInputStream(InputStream inputStream) throws IOException
{
byte[] b = new byte[1024];
String res = "";
int bytesRead = 0;
while (true) {
bytesRead = inputStream.read(b, 0, 1024);
if (bytesRead == -1) {
return res;
}
res += new String(b, 0, bytesRead, "UTF-8");
}
}