如何在Jboss EAP中覆盖CXF属性'maxChildElements'的值?

时间:2017-08-31 09:15:27

标签: java web-services jboss cxf

我在JBoss EAP 6.4.5环境中有JAX-WS Web服务端点集成。服务返回XML,它有超过50,000个子元素,我收到异常:

Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.stream.XMLStreamException: Maximum Number of Child Elements limit (50000) Exceeded]
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:436)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:372)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:349)
        at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:857) [cxf-rt-databinding-jaxb-2.7.17.redhat-1.jar:2.7.17.redhat-1]
        at org.apache.cxf.jaxb.JAXBEncoderDecoder.access$100(JAXBEncoderDecoder.java:101) [cxf-rt-databinding-jaxb-2.7.17.redhat-1.jar:2.7.17.redhat-1]
        at org.apache.cxf.jaxb.JAXBEncoderDecoder$2.run(JAXBEncoderDecoder.java:896) [cxf-rt-databinding-jaxb-2.7.17.redhat-1.jar:2.7.17.redhat-1]
        at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_60]
        at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:894) [cxf-rt-databinding-jaxb-2.7.17.redhat-1.jar:2.7.17.redhat-1]
        ... 263 more
Caused by: javax.xml.stream.XMLStreamException: Maximum Number of Child Elements limit (50000) Exceeded
        at com.ctc.wstx.sr.InputElementStack.push(InputElementStack.java:340) [woodstox-core-asl-4.4.1.jar:4.4.1]
        at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2951) [woodstox-core-asl-4.4.1.jar:4.4.1]
        at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2839) [woodstox-core-asl-4.4.1.jar:4.4.1]
        at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1073) [woodstox-core-asl-4.4.1.jar:4.4.1]
        at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:196)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:370)
        ... 269 more

如何覆盖属性'maxChildElements'?

1 个答案:

答案 0 :(得分:0)

您可以将其添加到独立的* .xml(*此处是完整的,完整的ha等),直接位于标记下,例如:

<server xmlns="urn:jboss:domain:13.0">
    <extensions>
      ...
    </extensions>
    <system-properties>
        <property name="org.apache.cxf.stax.maxChildElements" value="100000"/>
</system-properties> 

在wildfly 20上进行了测试,也许它也可以在您的环境中使用

更新[2020-09-23]

由于某些原因,我不太喜欢这种解决方案,因此最终我不得不在我的jboss-deployment-structure.xml中排除webservices子系统

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="javax.jws.api"/>
            <module name="javax.xml.ws.api"/>
            <module name="org.springframework.spring">
                <imports>
                    <include path="META-INF"/>
                </imports>
                <exports>
                    <include path="META-INF"/>
                </exports>
            </module>
            <module name="org.apache.cxf">
                <imports>
                    <include path="META-INF/cxf"/>
                    <include path="META-INF"/>
                </imports>
                <exports>
                    <include path="META-INF/cxf"/>
                    <include path="META-INF"/>
                </exports>
            </module>
            <module name="org.apache.cxf.impl">
                <imports>
                    <include path="META-INF/cxf"/>
                    <include path="META-INF"/>
                </imports>
                <exports>
                    <include path="META-INF/cxf"/>
                    <include path="META-INF"/>
                </exports>
            </module>
        </dependencies>
        <exclude-subsystems>
            <subsystem name="webservices"/>
        </exclude-subsystems>
    </deployment>
</jboss-deployment-structure>

然后是我的beans.xml文件(在本例中,我将其命名为jbossws-cxf.xml)

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" xmlns:context="http://www.springframework.org/schema/context" xmlns:cxf="http://cxf.apache.org/core" xmlns:soap="http://cxf.apache.org/bindings/soap" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
        http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
        http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd" default-lazy-init="false">
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
    <context:component-scan base-package="my.class.package"/>
    <bean id="sampleEndPointImpl" class="my.class.package.MyserviceImplemenation"/>
    <jaxws:server id="POJOEndpoint"
    address="/lol"
    serviceName="s:myServiceNameInWsdlFileLol"
    endpointName="e:portTypeNameInMyWsdlFileLol"
    xmlns:e="http://www.My-endpoint-url.com/service"
    xmlns:s="http://www.My-endpoint-url.com/service">
        <jaxws:serviceBean>
            <bean class="my.class.package.MyserviceImplemenation"/>
        </jaxws:serviceBean>
        <jaxws:properties>
            <entry key="org.apache.cxf.stax.maxChildElements" value="100000"/>
        </jaxws:properties>
    </jaxws:server>
</beans>

和我的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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">
    <servlet>
        <servlet-name>myservice</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/jbossws-cxf.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <servlet-mapping>
        <servlet-name>myService</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

注意:

我的类必须使用spring注释和CDI注释进行注释,即

@Stateless <- cdi annotation
@Component <- spring annotation
public class MyRandomClass {

    public String test(){
        return new String("test");
    }

}
我在其中使用的

@WebService(
        serviceName = "myServiceNameinWsdlLol",
        portName = "myportTypeNameInWSDLLol",
        targetNamespace = "http://www.my-tns-namespace.com/myService",
        wsdlLocation = "WEB-INF/wsdl/mywsdl.wsdl",
        endpointInterface = "com.my-tns-namespace.randompackage.myService"
) <- javax annotation
@Service <- spring annotation
public class MyServiceImplementation implements MyServiceEndpointInterface {

    @Inject <- javax annotation
    MyRandomClass myRandomClass;

    @Override
    public ResponseLol myServiceMethod(RequestLol request) {
        ResponseLol response = new ResponseLol();
        return responseLol;
    }
}

注意:我使用诸如lol之类的词来表示该类或url是项目 自定义而不是特定于Java框架。