如何消除Apache CXF中Jetty的getRequestCharacterEncoding()日志警告
解决Apache CXF 4.0.1独立模式下Jetty的
getRequestCharacterEncoding()警告 问题背景
使用Apache CXF 4.0.1纯独立版本(无EE环境),通过Kotlin代码搭建SOAP端点,每次有请求进入时,Jetty会输出以下警告:
WARN o.e.j.s.h.ContextHandler - Unimplemented getRequestCharacterEncoding() - use org.eclipse.jetty.servlet.ServletContextHandler
该警告来自Jetty的ContextHandler类,因为它未实现getRequestCharacterEncoding()方法,Jetty官方提示使用ServletContextHandler替代。
解决方案
问题根源是CXF默认创建的Jetty引擎使用了基础的ContextHandler,我们需要手动构建Jetty服务器,替换为ServletContextHandler,并将CXF服务挂载到这个Servlet上下文里。
修改后的完整Kotlin代码如下:
import org.apache.cxf.Bus import org.apache.cxf.BusFactory import org.apache.cxf.jaxws.EndpointImpl import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine import org.eclipse.jetty.server.Server import org.eclipse.jetty.servlet.ServletContextHandler import org.eclipse.jetty.servlet.ServletHolder import org.apache.cxf.transport.servlet.CXFServlet import javax.xml.ws.soap.AddressingFeature import javax.xml.ws.Provider import javax.xml.ws.WebServiceProvider import javax.xml.ws.ServiceMode import javax.xml.ws.BindingType import javax.xml.ws.soap.SOAPBinding import javax.xml.soap.SOAPMessage // 自定义Jetty服务器创建逻辑 private fun prepareJettyServer(port: Int): JettyHTTPServerEngine { val server = Server(port) // 使用ServletContextHandler替代默认的基础ContextHandler val context = ServletContextHandler(ServletContextHandler.SESSIONS) context.contextPath = "/" server.handler = context // 配置并挂载CXF Servlet val cxfServlet = CXFServlet() val servletHolder = ServletHolder(cxfServlet) context.addServlet(servletHolder, "/*") // 初始化CXF Bus val bus = BusFactory.getDefaultBus() bus.setProperty("org.apache.cxf.transport.http.destination.phase", "user") // 创建并配置JettyHTTPServerEngine val engine = JettyHTTPServerEngine(server) engine.sendServerVersion = false return engine } // 发布SOAP端点 fun main() { val serviceUrl = "http://localhost:8081/soap/service" prepareJettyServer(8081) // 使用EndpointImpl手动发布,关联自定义Jetty环境 val bus = BusFactory.getDefaultBus() val endpoint = EndpointImpl(bus, Implementor, AddressingFeature(true)) endpoint.publish(serviceUrl) println("SOAP service started at $serviceUrl") } // 你的Implementor单例保持不变 @WebServiceProvider @BindingType(SOAPBinding.SOAP12HTTP_BINDING) @ServiceMode(Service.Mode.MESSAGE) object Implementor : Provider<SOAPMessage> { override fun invoke(soapMessage: SOAPMessage): SOAPMessage? { // 处理消息逻辑 return soapMessage } }
原理说明
ServletContextHandler是ContextHandler的子类,完整实现了getRequestCharacterEncoding()等ServletRequest相关方法,因此不会触发警告。- 手动构建Jetty服务器并挂载CXF Servlet,替代了CXF默认的基础ContextHandler配置,从根源上解决了警告问题。
内容的提问来源于stack exchange,提问作者Zordid
相关产品推荐
相关产品推荐

