`
sillycat
  • 浏览: 2487379 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

xfire后续问题补充

    博客分类:
  • SOA
阅读更多
xfire后续问题补充

问题一:xfire的方法中,需要知道request,从request取出client访问者的IP
webservice最终是基于HTTP的,所以也是一个HTTP请求到
<bean id="baseWebService" class="org.codehaus.xfire.spring.remoting.XFireExporter" lazy-init="false"
    abstract="true">
<property name="serviceFactory" ref="xfire.serviceFactory"/>
<property name="xfire" ref="xfire"/>
</bean>
最终是由XFireExporter在处理这个HTTP请求
再看源码
public class XFireExporter
        extends ServiceBean
        implements Controller, ServletContextAware
其实所谓的XFireExporter其实是spring的一个controller实现,所以里面是可以得到request的。

其中几个重要类的关系如下:
XFireExporter ---> XFireServletControllerAdapter --->XFireServletController
在一个HTTP请求发生的时候,就将当前的request和response放到了
private static ThreadLocal requests = new ThreadLocal();
private static ThreadLocal responses = new ThreadLocal();
ThreadLocal变量中,在XFireServletController上又提供了static方法取得这个变量。
所以,参考网上查找到得资料。

我们只需要在我们的webService的server端上添加如下方法:
HttpServletRequest request = XFireServletController.getRequest();
String ip = RequestUtil.getIpAddr(request);
System.out.println(ip);

其中RequestUtil.java是一个从request取得ip的积累,内容如下:
package com.sillycat.core.commons.utils;

import javax.servlet.http.HttpServletRequest;

public class RequestUtil {

public static String getIpAddr(HttpServletRequest request) {
   String ip = request.getHeader("x-forwarded-for");
   if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getHeader("Proxy-Client-IP");
   }
   if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getHeader("WL-Proxy-Client-IP");
   }
   if (StringUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getRemoteAddr();
   }
   return ip;
}

}


问题二:xfire和spring-mvc-2.5.6的配置冲突

公司在使用spring-mvc的时候,使用了controller的默认view名字设置(具体参考spring的文档),文档上的配置如下:
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
<bean class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator" />

同时项目中又实用了xfire的简单映射配置(具体参考xfire文档)
<import resource="classpath:org/codehaus/xfire/spring/xfire.xml" />
<bean id="baseWebService" class="org.codehaus.xfire.spring.remoting.XFireExporter"
lazy-init="false" abstract="true">
<property name="serviceFactory" ref="xfire.serviceFactory" />
<property name="xfire" ref="xfire" />
</bean>
<bean name="ProjectXFire" parent="baseWebService">
<property name="serviceBean" ref="projectXFireImpl"/>
<property name="serviceClass" value="cn.sccl.icpmis.requirement.webService.ProjectXFire"/>
</bean>
启动后,系统报错如下:
2008-12-13 15:47:52 org.apache.catalina.core.StandardContext listenerStart
严u-28211 : Exception sending context initialized event to listener instance of class cn.sccl.common.web.StartupListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping#0' defined in ServletContext resource [/WEB-INF/classes/core-context.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot map handler [TaskSearchServiceEn] to URL path [/xfireexporter*]: There is already handler [org.codehaus.xfire.spring.remoting.XFireExporter@11c19e6] mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at cn.sccl.common.web.StartupListener.contextInitialized(StartupListener.java:20)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
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.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.lang.IllegalStateException: Cannot map handler [TaskSearchServiceEn] to URL path [/xfireexporter*]: There is already handler [org.codehaus.xfire.spring.remoting.XFireExporter@11c19e6] mapped.
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:304)
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:276)
at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.detectHandlers(AbstractDetectingUrlHandlerMapping.java:82)
at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:57)
at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:119)
at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:69)
at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:73)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:70)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:350)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1331)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
... 30 more

后来找到了是由于这两个配置的冲突导致的。查找spring源码
特别关注这几个类:
ControllerClassNameHandlerMapping --->AbstractControllerUrlHandlerMapping --->ControllerTypePredicate
其中的方法
protected boolean isControllerType(Class beanClass) {
这是判断spring容器中的bean是否是一个controller的,如果是,那么就将把view名字默认映射出去。每个xfire的配置都是基于XFireExporter的,都被认为是一个
controller,所以都按照相同的名字/xfireexporter*映射出去。所以就会报错。
我修改的办法比较笨,自己拷贝 ControllerClassNameHandlerMapping 类,增加了一个方法
@Override
public boolean isControllerType(Class beanClass) {
boolean flag = (Controller.class.isAssignableFrom(beanClass) || ThrowawayController.class
    .isAssignableFrom(beanClass));
if (org.codehaus.xfire.spring.remoting.XFireExporter.class.isAssignableFrom(beanClass)) {
   flag = false;
}
return flag;
}
将基类里面的方法override了,然后修改spring的配置文件为:
<bean class="cn.sccl.common.web.CustomerControllerClassNameHandlerMapping" />
<bean class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator" />

问题解决了。
1
0
分享到:
评论
1 楼 hbzjzh 2011-02-26  
华仔 你太帅了!

相关推荐

Global site tag (gtag.js) - Google Analytics