JAVA服务端实现HTTP请求的方式有很多种(比如常见的socket操作),本文介绍采用Apache Jakarta Common下的子项目HttpClient来实现,个人当时引入此工具包主要为实现单点登录能力
关于单点登录场景有很多解决,比如常见的 CAS 统一鉴权中心,但这依赖于一个统一的 CAS 服务。
而本文当时所遇到的场景是,鉴权中心仅能提供一个接口供调用。
实现站点间交互、需要获取他人的鉴权返回信息实现同步登录等场景。
最简单是直接使用 ajax 进行跨域请求,并获取返回进行处理。
鉴权中心同意开放跨域访问,后来通过评审我们一致认为这种方式有很大的安全隐患。
稍微懂点技术的 Hacker 使用一个开源的 BurpSuite 就能篡改请求&返回进行伪造登陆。
Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。
实现了所有 HTTP 的方法 GET,POST,PUT,HEAD 等。
简而言之,HttpClient 最大的作用是为了实现在服务端发送 Http 请求
public class MyTestServiceRequest extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "stdout");
String url = 请求地址;
String xmlString = 需要发送的XML格式信息;
HttpClient client = new HttpClient();
PostMethod myPost = new PostMethod(url);
//超时时间
client.getParams().setSoTimeout(300*1000);
String responseString = null;
try{
//设置请求头
myPost.setRequestEntity(new StringRequestEntity(xmlString,"text/xml","utf-8"));
//执行发送
int statusCode = client.executeMethod(myPost);
//如果返回码200,成功
if(statusCode == HttpStatus.SC_OK)
{
BufferedInputStream bis = new BufferedInputStream(myPost.getResponseBodyAsStream()); //读取rsp的body体
byte[] bytes = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int count = 0;
while((count = bis.read(bytes))!= -1)
{
bos.write(bytes, 0, count);
}
byte[] strByte = bos.toByteArray();
responseString = new String(strByte,0,strByte.length,"utf-8"); //转成String
Map<String,String> authMap = new HashMap<String,String>();
if(null!=responseString&&!"".equals(responseString))
{
//String转XML
authMap = xmlElements(responseString);
//鉴权成功
if("true".equals(authMap.get("result")))
{
//远程鉴权成功的后续操作
}else{
//远程鉴权失败的后续操作
}
}
bos.close();
bis.close();
}
}catch (Exception e) {
//异常处理
}
myPost.releaseConnection();
client.getHttpConnectionManager().closeIdleConnections(0);
}
/**
* 解析返回的XMLBody体
*/
public Map<String,String> xmlElements(String xmlDoc) {…略…}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
this.doPost(req, resp);
}
}
这个实例意义不大,JAVA 服务端接受 POST 请求直接用常规 Servlet 即可。
public class MyTestServiceResponse extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
InputStream is = request.getInputStream(); //获取HTTP请求的输入流
BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8")); //以HTTP请求输入流建立一个BufferedReader对象
String buffer = null; //读取HTTP请求内容
StringBuffer sb = new StringBuffer();
while ((buffer = br.readLine()) != null)
{
sb.append(buffer+"n"); //读取所有的信息,并追加 转行
}
PrintWriter out = response.getWriter();
StringBuffer stringBuffer = new StringBuffer("<?xml version="1.0" encoding="UTF-8"?>");//建议返回体
stringBuffer.append("返回信息");
……
stringBuffer.append("返回信息");
out.write(stringBuffer.toString());
out.flush();
out.close();
} catch (Exception e) {
//异常处理
}
}
}
本质上来讲采用 HttpClient 实现服务端处理 http 请求的意义不是很大,现在 SpringMVC 和 struts 相当易用。
温馨提示:系统将通过浏览器临时记忆您曾经填写的个人信息且支持修改,评论提交后仅自己可见,内容需要经过审核后方可全面展示。