【问题标题】:Getting cookies in XmlRpc Service在 XmlRpc 服务中获取 cookie
【发布时间】:2013-01-28 15:41:11
【问题描述】:


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

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)

因为我确定我通过添加RequestContextFilter 正确配置了web.xml,所以这句话

您指的是实际网络之外的请求属性 请求,或处理原始接收之外的请求 线程?

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

【问题讨论】:

    标签: java spring apache tomcat6 xml-rpc


    【解决方案1】:

    我们找到了一种解决方法,它可能在未来对他人和我们自己有用,所以我将我们的解决方案作为参考,我们从另一个角度看待问题。
    我们意识到 XmlRpcServlet 实际上是一个 servlet(真是令人惊讶),所以我们认为应该有一个 doPost 方法来服务请求。查看XmlRpcServlet 的源代码,实际上有一个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-07-23
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 2011-08-05
      • 2011-01-13
      • 2011-03-14
      相关资源
      最近更新 更多