【发布时间】: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