在项目中,可能存对Hessian的特殊的要求改造,以下两个例子就是我在项目中遇到的
一、对服务器方法调用前做一些校验,获取客户端请求参数
实现方法:继承com.caucho.hessian.server.HessianServlet重写service方法,代码如下:
/**
* 本地化的HessianServlet,用于服务务器方法调用前的校验
*
* @author ZhangMingxue
*
*/
public class MHessianServlet extends HessianServlet {
private static final long serialVersionUID = 1620619522783394602L;
@SuppressWarnings("unchecked")
@Override
public void service(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
System.out.println("服务器方法调用前");
// 在service方法中可以将request强转成HttpServletRequest,就可以获取很多信息
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getContextPath();
String basePath = req.getScheme() + "://" + req.getServerName() + ":"
+ req.getServerPort() + path + "/";
// 1.获取客户端请求路径
String requestURI = req.getRequestURI();
System.out.println(basePath);
System.out.println(requestURI);
// 2.获取客户端参数信息
Enumeration<String> parameterNames = req.getParameterNames();
if (null != parameterNames) {
while (parameterNames.hasMoreElements()) {
String paramterValue = req.getParameter(parameterNames
.nextElement());
System.out.println(paramterValue);
}
}
// 3.会话管理 ...
super.service(request, response);
System.out.println("服务器方法调用后");
}
}
配置如下:配置成自己继承后的Servlet
<servlet> <servlet-name>HelloServlet2</servlet-name> <!-- 自己继承后的Servlet --> <servlet-class>com.mengya.hessian.MHessianServlet</servlet-class> <init-param> <param-name>home-class</param-name> <param-value>com.mengya.imple.HelloImple</param-value> </init-param> <init-param> <param-name>home-api</param-name> <param-value>com.mengya.inter.IHello</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>HelloServlet2</servlet-name> <url-pattern>/HelloServlet2</url-pattern> </servlet-mapping>
客户端测试:
public class Hello2Test {
public static void main(String[] args) {
// 服务器访问路径
String url = "http://127.0.0.1:8080/HessianDemos/HelloServlet2?method=add¶m=p1";
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
try {
// IHello是客户端的接口,与服务器接口一致(客户端的语言包括:Java,Objective C,Flex 等)
IHello iHello = (IHello) hessianProxyFactory.create(IHello.class,
url);
// 客户端调服务器的接口实现
System.out.println("Result == " + iHello.sayHello());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
二、获取客户端的请求URL,对于特殊的URL重新转发,继承Hessian的Servlet,改造service和invoke方法
实现代码如下:
/**
* 本地化的HessianServlet,用于请求转发
*
* @author ZhangMingxue
*
*/
public class ForwardHessianServlet extends HessianServlet {
private static final long serialVersionUID = 4497196628911041481L;
@Override
public void service(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
// 客户端的请求路径
String requestURI = req.getRequestURI();
this.realizeService(request, response, requestURI);
}
// 在原service()方法添加了一个参数
@SuppressWarnings("deprecation")
public void realizeService(ServletRequest request,
ServletResponse response, String requestURI) throws IOException,
ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (!req.getMethod().equals("POST")) {
res.setStatus(500, "Hessian Requires POST");
PrintWriter out = res.getWriter();
res.setContentType("text/html");
out.println("<h1>Hessian Requires POST</h1>");
return;
}
String serviceId = req.getPathInfo();
String objectId = req.getParameter("id");
if (objectId == null)
objectId = req.getParameter("ejbid");
ServiceContext.begin(req, serviceId, objectId);
try {
InputStream is = request.getInputStream();
OutputStream os = response.getOutputStream();
response.setContentType("application/x-hessian");
SerializerFactory serializerFactory = getSerializerFactory();
// 修改为调用自己的invoke方法
this.invoke(is, os, objectId, serializerFactory, requestURI);
} catch (RuntimeException e) {
throw e;
} catch (ServletException e) {
throw e;
} catch (Throwable e) {
throw new ServletException(e);
} finally {
ServiceContext.end();
}
}
protected void invoke(InputStream is, OutputStream os, String objectId,
SerializerFactory serializerFactory, String requestURI)
throws Exception {
URL url = null;
HttpURLConnection conn = null;
try {
// 客户端请求原始URL
System.out.println(requestURI);
// 根据实际情况,转向到别一个服务器中
url = new URL("http://127.0.0.1:8080/HessianDemos/HelloServlet");
System.out.println("转向到:" + url);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "x-application/hessian");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
OutputStream ros = conn.getOutputStream();
byte[] buff = new byte[1024 * 64];
int length;
while ((length = is.read(buff)) > 0) {
ros.write(buff, 0, length);
}
ros.flush();
ros.close();
InputStream ris = conn.getInputStream();
while ((length = ris.read(buff)) > 0) {
os.write(buff, 0, length);
}
ris.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null)
conn.disconnect();
}
}
}
配置如下:
<servlet> <servlet-name>ForwardHelloServlet</servlet-name> <servlet-class>com.mengya.hessian.ForwardHessianServlet</servlet-class> <init-param> <param-name>home-class</param-name> <param-value>com.mengya.imple.HelloImple</param-value> </init-param> <init-param> <param-name>home-api</param-name> <param-value>com.mengya.inter.IHello</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ForwardHelloServlet</servlet-name> <url-pattern>/ForwardHelloServlet</url-pattern> </servlet-mapping>
客户端测试代码:
public class ForwardHelloTest {
public static void main(String[] args) {
// 服务器访问路径
String url = "http://127.0.0.1:8080/HessianDemos/ForwardHelloServlet";
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
try {
// IHello是客户端的接口,与服务器接口一致(客户端的语言包括:Java,Objective C,Flex 等)
IHello iHello = (IHello) hessianProxyFactory.create(IHello.class,
url);
// 客户端调服务器的接口实现
System.out.println("Result == " + iHello.sayHello());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}