情景:有一个生成PDF的接口中,如下:
@GET
@Path("/getPDF")
public void getPDF(@QueryParam("id") String id, @Context HttpServletResponse response) {
…………
}
之前实现的代码都写在了Controller里面,代码里还不少,有几个方法。我想把实现代码移到Service中,调用Service实现。如下:
@Reference(version = "1.0.0")
private PDFService pdfService;
@GET
@Path("/getPDF")
public void getPDF(@QueryParam("id") String id, @Context HttpServletResponse response) {
pdfService.getPDF(id, response);
}
项目使用的是Zookeeper + Dubbo的组合,远程调用PDFService的getPDF()方法实现。重新运行时,报下面的错误:
cause: Serialized class org.jboss.resteasy.core.ContextParameterInjector$GenericDelegatingProxy must implement java.io.Serializable
Java field: protected java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.h
解决: Dubbo传递的对象要能被序列化,即实现序列化接口。HttpServletResponse response
不能被序列化,所以报错。
这点很容易被忽略,之前我遇到过一个问题和这个类似。项目中有个日志Aspect,会记录下用户操作的日志,内容包括访问的用户信息,方法名,方法参数列表等。结果因为某个方法参数中有HttpServletResponse response
,不能序列化,日志代码报错,然后最终导致用户访问的这个接口操作失败,数据回滚。
最后,上面的代码我改为远程调用获取PDF数据,返回byte[],不传递response,而是在controller中将byte[]和response拼在一起。