更改Http请求中的内容

起因是这样的,与其他公司的系统集成,通信使用 xml-rpc ,xml-rpc 规范参考http://www.xmlrpc.com/spec。
现在有这样一个请求:

<?xml version="1.0" encoding="utf-8"?>
<methodCall>
   <methodName>GetRtVideoTicket</methodName>
   <params>
      <param>
         <value><string>string</string></value>
         </param>
      </params>
  </methodCall>

     也就是说,客户端请求执行一个方法。但是 java 语言中没有独立存在的方法,而apchce的xml-rpc实现中我也没找到响应这种请求的方法,必须先注册一个处理类handler,客户端才能调用这个类对象的方法。上面这个请求中,方法名要这样写才能调用成功:
<methodName>handler.GetRtVideoTicket</methodName>
      对方的系统使用的是 .net + ext 实现,好像 c# 跟 c++ 一样,有不依赖于具体类对象的方法(函数)存在。对方的系统已部署运行,且不会更改客户端,我只会java,在有限的时间实现服务端,只能使用自己熟悉的语言,可能的方法就是http请求过来的时候,把它请求的方法名自己做些改造。也就是将客户端请求方法名由“GetRtVideoTicket”改为“handler.GetRtVideoTicket”。

      在服务端Servlet,其中的HttpServletRequest对象是不可修改的,它有大量的get方法,确只有区区2个set方法:
httpRequest.setAttribute(name, o);
httpRequest.setCharacterEncoding(env);
      这时,可以使用 filter ,在请求到达 Servlet 前将HttpServletRequest对象替换掉。

      javaee中提供了一个HttpServletRequest的包装类HttpServletRequestWrapper,我们可以通过它对HttpServletRequest对象做些处理:
public class MyServletRequestWrapper extends HttpServletRequestWrapper {

  public MyServletRequestWrapper(HttpServletRequest request) {
    super(request);
  }
  ......
}
      比如,覆写它的getInputStream() 方法,就可以用我们自己的InputStream对象,替换掉http请求里的InputStream对象:
@Override
 public ServletInputStream getInputStream() throws IOException {
  String data = getStreamString(super.getInputStream());
  //这里只是简单的替换做示例,正确的做法是把<methodName>标签对里的方法名加上"handler."前缀
  data = data.replaceAll("GetRtVideoTicket", "handler.GetRtVideoTicket");
  InputStream in = getStringStream(data);
  return (ServletInputStream) in;
 }
      上面有字符串和字节流互相转换的方法,如下:
//从字符串获得字节流
private InputStream getStringStream(String data) {
  if (!"".equals(data)) {
   MyServletInputStream in = new MyServletInputStream(data);
   return in;
  }
  return null;
 }


 //从字节流获得字符串
private String getStreamString(InputStream in) {
  if (in != null) {
   try {
    BufferedReader tBufferedReader = new BufferedReader(
      new InputStreamReader(in));
    StringBuffer tStringBuffer = new StringBuffer();
    String sTempOneLine = new String("");
    while ((sTempOneLine = tBufferedReader.readLine()) != null) {
     tStringBuffer.append(sTempOneLine);
    }
    return tStringBuffer.toString();
   } catch (Exception ex) {
    ex.printStackTrace();
   }
  }
  return null;
 }


由于http请求对象里的InputStream对象类型是ServletInputStream,而ServletInputStream是一个抽象类,因此从字符串获得字节流的方法中,使用了扩展至ServletInputStream的子类,MyServletInputStream类如下:

public class MyServletInputStream extends ServletInputStream {

 private ByteArrayInputStream byteArrIn = null;
 
 public MyServletInputStream(String data) {
  byteArrIn = new ByteArrayInputStream(data.getBytes());
 }
 
 @Override
 public int read() throws IOException {
  return byteArrIn.read();
 }
}


MyServletRequestWrapper包装类,需要通过过滤器来应用:
public class RequestFilter implements Filter {


 private FilterConfig filterConfig;
 
 public void destroy() {
  this.filterConfig = null;
 }


 public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {
  //用包装类来替换http请求对象
  chain.doFilter(new MyServletRequestWrapper((HttpServletRequest) request), response);
 }


 public void init(FilterConfig filterConfig) throws ServletException {
  this.filterConfig = filterConfig;
 }


}


      在web.xml文件中配置过滤器
  <filter>
    <filter-name>myFilter</filter-name>
    <filter-class>xmlrpc.filter.RequestFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/MyXmlRpcServer</url-pattern>
  </filter-mapping>


      至此,客户端请求的内容,已被替换掉了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值