【问题标题】:Apache CXF interceptors not triggered in WebLogic 12c?WebLogic 12c 中未触发 Apache CXF 拦截器?
【发布时间】:2014-09-24 20:33:24
【问题描述】:

拜托,我被困了很多天,总是出现同样的错误。我正在测试 helloWorld apache cxf 示例,其中我添加了一个拦截器以从 HTTP 标头获取信息。

我正在使用 IDEA Intellij 11.0.2 进行开发,当我在 Intellij 中对其进行测试时,它工作得非常好,但是当我在 WebLogic 12c 中部署工件时,我总是遇到空指针异常。

我的个人计算机 (Windows 7 Professional) 的本地 WebLogic 12c 和 UNIX 服务器 AIX 7.1 的 WebLogic 12c 中也出现了同样的错误。

我使用 JDK 1.7.0 和 Apache CXF 2.7.12。

当我在 IDEA Intellij 中调试代码时,我看到拦截器构造函数已执行,并且 handleMessage 也已执行,因此一切正常。但是在 WebLogic 中调试时,构造函数被执行,但 handleMessage 从未被执行。

我的问题在于这行代码:

    Message message = PhaseInterceptorChain.getCurrentMessage(); 

当我在 IDEA Intellij 中执行/调试时,变量“消息”被正确填充,但在 WebLogic 中执行/调试时它始终为 NULL。无论如何,我认为问题发生在我写之前,因为在 WebLogic 中从未调用过“handleMessage”,但在 IDEA Intellij 中是。

我添加了一些在 IDEA Intellij 和 WebLogic 中调试的屏幕截图,以向您展示我的意思。我换了行:

    Message message = PhaseInterceptorChain.getCurrentMessage(); 

对于这 3 行,因为我看到我有相同的结果,但调试时要向您展示更多内容:

    Bus bus = BusFactory.getDefaultBus(); 
    PhaseInterceptorChain chain = new PhaseInterceptorChain(bus.getExtension(PhaseManager.class).getInPhases()); 
    Message message = chain.getCurrentMessage(); 

这是我在 Intellij 中调试时得到的结果(一切正常):

--> 抱歉,在获得至少 10 个声望之前我不能发布图片。无论如何,这里我展示了拦截器是通过编程方式添加的,并且在运行时,拦截器中的构造函数和 handleMessage 被执行,所以一切正常。正确填充了“bus”、“chain”和“message”。

这就是我在 WebLogic 中调试时得到的结果(没有按预期工作):

--> 抱歉,在获得至少 10 个声望之前我不能发布图片。无论如何,这里我展示了拦截器是在运行时以编程方式添加的,拦截器中的构造函数被执行,但拦截器中的 handleMessage 从未执行所以最后我有一个错误,因为“总线”,“链”被填充但“消息”为空。

最后,一些代码:

1) HelloWorldImpl.java

package example; 

import org.apache.cxf.Bus; 
import org.apache.cxf.BusFactory; 

import javax.jws.WebMethod; 
import javax.jws.WebService; 

import org.apache.cxf.message.Message; 
import org.apache.cxf.phase.PhaseInterceptorChain; 
import org.apache.cxf.phase.PhaseManager; 

@WebService() 
public class HelloWorldImpl implements HelloWorld { 

    public HelloWorldImpl() { 
        Bus bus = BusFactory.getDefaultBus(); 
        UserCredentialInterceptor myInterceptor = new UserCredentialInterceptor(); 
        bus.getInInterceptors().add(myInterceptor); 
    } 

    @WebMethod 
    public String sayHelloWorldFrom(String from) { 
        //Message message = PhaseInterceptorChain.getCurrentMessage(); 
        Bus bus = BusFactory.getDefaultBus(); 
        PhaseInterceptorChain chain = new PhaseInterceptorChain(bus.getExtension(PhaseManager.class).getInPhases()); 
        Message message = chain.getCurrentMessage(); 
        if (message==null) { 
            System.out.println("HELLOWORLD ERROR"); 
        } else { 
            System.out.println("HELLOWORLD OK"); 
        } 

        String result = "Hello, world, from " + from; 
        System.out.println(result); 
        return result; 
    } 
} 

2) UserCredentialInterceptor.java

package example; 

import org.apache.cxf.binding.soap.SoapMessage; 
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; 
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor; 
import org.apache.cxf.interceptor.Fault; 
import org.apache.cxf.phase.Phase; 
import org.apache.cxf.transport.http.AbstractHTTPDestination; 
import org.w3c.dom.NodeList; 
import javax.servlet.http.HttpServletRequest; 
import javax.xml.soap.SOAPException; 
import javax.xml.soap.SOAPHeader; 
import javax.xml.soap.SOAPMessage; 
import java.util.Enumeration; 
import javax.servlet.http.Cookie; 

public class UserCredentialInterceptor extends AbstractSoapInterceptor { 
    private SAAJInInterceptor saajIn = new SAAJInInterceptor(); 

    public UserCredentialInterceptor() { 
        super(Phase.PRE_PROTOCOL); 
        getAfter().add(SAAJInInterceptor.class.getName()); 
    } 

    public void handleMessage(SoapMessage message) throws Fault { 
        SOAPMessage doc = message.getContent(SOAPMessage.class); 
        if (doc == null) { 
            saajIn.handleMessage(message); 
            doc = message.getContent(SOAPMessage.class); 
        } 
        SOAPHeader headerr = null; 
        try { 
            headerr = doc.getSOAPHeader(); 
        } catch (SOAPException e) { 
            e.printStackTrace(); 
        } 
        if (headerr != null) { 
            NodeList nodes = headerr.getElementsByTagNameNS("http://asjava.com/types", "Username"); 
            if (nodes != null && nodes.item(0) != null) { 
                String user = nodes.item(0).getTextContent(); 
            } 
        } 
        //if you want to read more http header messages, just use get method to obtain from  HttpServletRequest. 
        HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST); 
        if(null!=request){ 
            //Read http header to get client IP adress 
            String addr = request.getRemoteAddr(); 
            //Read http header to get HeaderNames 
            Enumeration enums = request.getHeaderNames(); 
            //Read http header to get cookie/ 
            Cookie[] cookies = request.getCookies(); 
        } 
    } 
} 

3) 应用程序.xml

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE application PUBLIC 
        "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" 
        "http://java.sun.com/dtd/application_1_3.dtd"><application>
    <display-name>test_interceptors</display-name>
    <module>
        <web>
            <web-uri>/</web-uri>
            <context-root>/</context-root>
        </web>
    </module>
</application>

4) weblogic-application.xml

<?xml version="1.0" encoding="UTF-8"?> 
<wls:weblogic-application xmlns:wls="http://www.bea.com/ns/weblogic/weblogic-application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_5.xsd http://www.bea.com/ns/weblogic/weblogic-application http://www.bea.com/ns/weblogic/weblogic-application/1.0/weblogic-application.xsd">
    <wls:application-param>
        <wls:param-name>webapp.encoding.default</wls:param-name>
        <wls:param-value>UTF-8</wls:param-value>
    </wls:application-param>
    <wls:prefer-application-packages>
        <wls:package-name>javax.wsdl.*</wls:package-name>
        <wls:package-name>javax.ws.rs.*</wls:package-name>
    </wls:prefer-application-packages>
</wls:weblogic-application>

5) web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

    <description>cxf</description>

    <display-name>cxf</display-name>
    <servlet>
        <description>Apache CXF Endpoint</description>
        <display-name>cxf</display-name>
        <servlet-name>cxf</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxf</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
</web-app>

6) weblogic.xml

<weblogic-web-app 
        xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">

    <container-descriptor>
        <prefer-web-inf-classes>true</prefer-web-inf-classes>
    </container-descriptor>

</weblogic-web-app>

7) cxf-servlet.xml

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:cxf="http://cxf.apache.org/core"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xmlns:soap="http://cxf.apache.org/bindings/soap"
      xsi:schemaLocation=" 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
</beans>

请,非常感谢任何帮助。

谢谢 菲利克斯·梅卡德。

【问题讨论】:

  • 那是一个巨大的代码块。尝试阅读how to askfirst。通读所有这些(大部分是不必要的)代码行非常困难
  • 我想添加两个图像,因为它们显示了我在 Intellij 或 WebLogic 中调试时的所有差异。但我不能,因为我没有至少 10 个声望。无论如何,我的问题在于 Message message = PhaseInterceptorChain.getCurrentMessage(); “消息”在 Intellij 中正确填充,但在 WebLogic 中为空。

标签: apache cxf interceptor weblogic12c


【解决方案1】:

您的 cxf-servlet.xml 根本没有定义任何 bean。因此,我猜 Weblogic JAX-WS 实现正在触发和部署服务,甚至没有使用 CXF。在服务中执行 Thread.dumpStack 以查看正在获取的实现。我敢打赌那里没有任何 org.apache.cxf 东西。

【讨论】:

  • 丹尼尔,非常感谢您的帮助。是的,我知道,我的 cxf-servlet.xml 没有定义任何 bean。但我也尝试在 cxf-servlet.xml 中添加以下 bean:
    我现在要在 WebLogic 中尝试 Thread.dumpStack(),我会告诉你我所看到的。目前我可以确认在 Intellij 中我看到了很多对 cfx 的引用。例如:在 org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:107) 在 org.apache.cxf.phase 的 org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)。 PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
  • 丹尼尔!太感谢了 !是的,WebLogic 中的 Thread.dumpStack 显示了完全不同的东西。没有引用 cxf,只引用 jaxws,所以你是完全正确的。现在我要将我的 bean 放回 cxf-servlet.xml 但我确信这不会解决问题。我很确定 Thread.dumpStack() 仍然不会显示任何 cxf 内容。无论如何,这是一个很好的领导!再次感谢!
  • Daniel... 我正在按照cxf.apache.org/docs/… 此处的说明在 WebLogic 中部署 Apache CXF,但没有办法。这没用。始终使用 jaxws 而不是 cxf。无论如何,在那个链接中它说它在 WebLogic 9.2 上得到了验证,我正在使用 WebLogic 12c。有什么建议吗?谢谢
  • 我在这里打开了一个新主题,现在我发现问题不是拦截器而是 CXF 没有被使用:stackoverflow.com/questions/26038187/…
猜你喜欢
相关资源
最近更新 更多
热门标签