1


我建议你这将是一个很长的帖子,因为我真的不知道我想做的事情是否可行,我什至在定义我的需求时遇到了一些问题。
基本上,我被要求扩展一个Apache XML-RPC Server,以便可以访问 cookie。我查看了一些文档,我需要扩展的服务是按照官方Apache 指南创建的。我的服务看起来像(取自指南的示例代码):

package org.apache.xmlrpc.demo;
public class Calculator {
  public int add(int i1, int i2) {
    return i1 + i2;
  }
  public int subtract(int i1, int i2) {
    return i1 - i2;
  }
}

我们用来公开这个服务的 servlet 是标准的org.apache.xmlrpc.webserver.XmlRpcServlet,我们在Tomcat6. 也就是说,我需要修改Calculator才能从 cookie 中获取一些数据,比如

public int add(int i1, int i2) {
  Cookie[] cookies = //how to do this?
  return i1 + i2;
}

由于我们正在使用Spring我尝试修改Calculator请求Autowired,例如

package org.apache.xmlrpc.demo;
@Configurable
@Scope("request")
public class Calculator {

  @Autowired HttpServletRequest request;
  //...
}

但通过这种方式我获得了一个例外

    Failed to invoke method searchFlights in class com.bravofly.bsa4.server.FlightsServiceXmlRpc: 
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? 
If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: 
In this case, use RequestContextListener or RequestContextFilter to expose the current request.

    org.apache.xmlrpc.common.XmlRpcInvocationException: Failed to invoke method searchFlights in class com.bravofly.bsa4.server.FlightsServiceXmlRpc: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
        at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.invoke(ReflectiveXmlRpcHandler.java:129)
        at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.execute(ReflectiveXmlRpcHandler.java:106)
        at org.apache.xmlrpc.server.XmlRpcServerWorker.execute(XmlRpcServerWorker.java:46)
        at org.apache.xmlrpc.server.XmlRpcServer.execute(XmlRpcServer.java:86)
        at org.apache.xmlrpc.server.XmlRpcStreamServer.execute(XmlRpcStreamServer.java:200)
        at org.apache.xmlrpc.webserver.XmlRpcServletServer.execute(XmlRpcServletServer.java:112)
        at org.apache.xmlrpc.webserver.XmlRpcServlet.doPost(XmlRpcServlet.java:196)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:159)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:202)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:175)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
    Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
        at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
        at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:231)
        at org.springframework.web.context.support.WebApplicationContextUtils.access$0(WebApplicationContextUtils.java:230)
        at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:245)
        at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:1)
        at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:178)
        at $Proxy73.getCookies(Unknown Source)
        at com.bravofly.bsa4.server.FlightsServiceXmlRpc.searchFlights(FlightsServiceXmlRpc.java:57)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.invoke(ReflectiveXmlRpcHandler.java:115)
        ... 31 more
    Caused by:
    java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
        at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
        at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:231)
        at org.springframework.web.context.support.WebApplicationContextUtils.access$0(WebApplicationContextUtils.java:230)
        at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:245)
        at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:1)
        at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:178)
        at $Proxy73.getCookies(Unknown Source)
        at com.bravofly.bsa4.server.FlightsServiceXmlRpc.searchFlights(FlightsServiceXmlRpc.java:57)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.invoke(ReflectiveXmlRpcHandler.java:115)
        at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.execute(ReflectiveXmlRpcHandler.java:106)
        at org.apache.xmlrpc.server.XmlRpcServerWorker.execute(XmlRpcServerWorker.java:46)
        at org.apache.xmlrpc.server.XmlRpcServer.execute(XmlRpcServer.java:86)
        at org.apache.xmlrpc.server.XmlRpcStreamServer.execute(XmlRpcStreamServer.java:200)
        at org.apache.xmlrpc.webserver.XmlRpcServletServer.execute(XmlRpcServletServer.java:112)
        at org.apache.xmlrpc.webserver.XmlRpcServlet.doPost(XmlRpcServlet.java:196)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:159)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:202)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:175)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)

因为我确定我web.xml通过添加正确配置了RequestContextFilter,句子

您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?

在异常中让我觉得 XmlRpcServlet 在一个完全隔离的线程中运行(不知何故)我的计算器服务。如果我的猜测是正确的,有没有办法在我的服务中获取请求?如果我的猜测是错误的,我做错了什么?您是否还需要一些配置文件(web.xml,spring-context.xml等)来更好地评估我的问题?

4

1 回答 1

1

我们找到了一种解决方法,它可能对他人和未来再次对我们自己有用,所以我留下我们的解决方案作为参考,我们从另一个角度看待问题。
我们意识到XmlRpcServlet它实际上是一个 servlet(真是令人惊讶),所以我们认为应该有一种doPost方法来处理请求。查看XmlRpcServletinfact的源代码doPost,因此我们只需创建CustomXmlRpcServlet并覆盖读取那里的 cookie 的方法,将所需的值保存到已经可供我们使用的服务器对象中。

public class CustomXmlRpcServlet extends XmlRpcServlet
{

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
    Cookie[] cookies = request.getCookies();
    //...
    super.doPost(request, response);
  }
  //...
  //Tough we do not have other customization, here it is possible to add additional method and/or override existing ones
}

我们花了几天时间试图实现我们最初的目标,然后一个简单的视角改变以一种干净简单的方式解决了我们的问题。很高兴能在一个团队中!

于 2013-01-29T08:48:56.467 回答