2014-09-24 99 views
1

请多少天,我总是有同样的错误卡住了。我正在测试helloWorld apache cxf示例,其中我添加了一个拦截器以从HTTP标头获取信息。WebLogic 12c中没有触发Apache CXF拦截器?

我正在开发使用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(); 

当我执行中的IntelliJ IDEA /调试变量“消息”正确填充,但它始终是NULL,当我在WebLogic中执行/调试。无论如何,我认为这个问题发生之前,因为我写道,“handleMessage”从来没有在WebLogic中调用,但在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被执行,所以一切正常。 “总线”,“链”和“消息”正确填充。

这是我所得到的在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)的application.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-applicatio ñ。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> 

请,任何帮助非常感谢。

谢谢 Felix Mercader。

+0

这是一个巨大的代码块。首先尝试阅读[如何提问](http://stackoverflow.com/help/how-to-ask)。很难通读所有这些(大多数是不必要的)代码行 – 2014-09-24 09:46:00

+0

我想添加两个图像,因为它们显示了在Intellij或WebLogic中进行调试时所具有的所有差异。但我不能,因为我没有至少10个声望。无论如何,我的问题是在消息消息= PhaseInterceptorChain.getCurrentMessage(); “消息”在Intellij中正确填充,但在WebLogic中为空。 – 2014-09-24 10:07:26

回答

0

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

+0

丹尼尔,非常感谢你的帮助。是的,我知道,我的cxf-servlet.xml没有定义任何bean。但我还试图在CXF-servlet.xml中添加以下豆: <豆ID =“userCredentialInterceptor “class =”example.UserCredentialInterceptor> 和最终结果是一样的:拦截器的构造函数执行但从来没有handleMessage。当然这个问题再次出现在WebLogic中,因为在Intellij中工作得很好 – 2014-09-24 13:45:58

+0

我现在要去试试Thread.dumpStack ()在WebLogic中,我会告诉你我看到了什么,现在我可以确认在Intellij中我看到很多对cfx的引用,例如:\t at org.apache.cxf.workqueue.SynchronousE xecutor.execute(SynchronousExecutor.java:37) \t在org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:107) \t在org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java: 272) – 2014-09-24 13:48:29

+0

丹尼尔!非常感谢 !是的,WebLogic中的Thread.dumpStack显示完全不同的东西。没有引用cxf,只有jaxws,所以你是完全正确的。现在我要把我的bean放回到cxf-servlet.xml中,但我确信这不会解决问题。我很确定Thread.dumpStack()仍然不会显示任何cxf的东西。无论如何,这是一个很好的领先!再次感谢 ! – 2014-09-24 13:55:35