Configuring XML serializer/marshaller in Spring Boot application REST webservice












0















I'm trying to create a Spring REST WebService which will return a complex object to the caller. In particular this caller is going to be asking for the object using application/XML.



Without any particular configuration about the marshaller, the object is serialized correctly to XML to the caller, BUT it does not contain XML namespace information, so the object deserialization fails on the caller side (I cannot change the caller's code, and don't want to either).



This is the XML the client is receiving:



<SearchPoliciesResponse>
<searchPoliciesResult>
<searchHeader>
... snip


This is what they should be receiving:



<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<SearchPoliciesResponse xmlns="http://com.cgic.app.service.policy/PolicySearch">
<searchPoliciesResult>
<SearchHeader>
... snip


This is what my REST controller method looks like:



@PostMapping()
public SearchPoliciesResponse searchRequest(@Valid @RequestBody SearchPoliciesRequest request)
throws Exception {

var allPoliciesFile = ResourceUtils.getFile("classpath:policies/search/policy-summary.xml");
var jaxbContext = JAXBContext.newInstance(SearchPoliciesResponse.class);
var jaxbUnmarshaller = jaxbContext.createUnmarshaller();
var response = (SearchPoliciesResponse) jaxbUnmarshaller.unmarshal(allPoliciesFile);

// ... HERE I WILL MAKE SOME MANUAL CHANGES TO THE RESPONSE OBJECT

return response;
}


I tried adding the following Bean to my configuration class (SpringBootApplication annotated class), but to no effect:



@Bean
public Jaxb2Marshaller marshaller() {
var marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(SearchPoliciesResponse.class, SearchPoliciesRequest.class);

return marshaller;
}


I know that the classes I use for (de)serialization are correctly annotated, because (a) they were autogenerated by JAXB (xjc tool), and (b) if I manually create a JAXBContext and marshall to XML, it's serialized correctly with the namespace I'm expecting.



The policy classes package contains a package-info.java file with the correct QUALIFIED annotation on the package, so it should be working, and it is when done manually, for Spring.



To test if the Spring marshaller bean I declared would work, I tested injecting it:



@Autowired
private Jaxb2Marshaller marshaller;


And then tried marshalling manually



var writer = new StringWriter();
var result = new StringResult();
marshaller.marshal(response, result);


And it DID work fine. So it appears to be whatever happens between the REST controller return, and when Spring marshals the object, it's not using the Bean I declared.



I'm using:



springBootVersion = '2.0.4.RELEASE'
org.springframework.ws:spring-ws-core:3.0.4.RELEASE



I appreciate any hints.



Thank you










share|improve this question





























    0















    I'm trying to create a Spring REST WebService which will return a complex object to the caller. In particular this caller is going to be asking for the object using application/XML.



    Without any particular configuration about the marshaller, the object is serialized correctly to XML to the caller, BUT it does not contain XML namespace information, so the object deserialization fails on the caller side (I cannot change the caller's code, and don't want to either).



    This is the XML the client is receiving:



    <SearchPoliciesResponse>
    <searchPoliciesResult>
    <searchHeader>
    ... snip


    This is what they should be receiving:



    <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
    <SearchPoliciesResponse xmlns="http://com.cgic.app.service.policy/PolicySearch">
    <searchPoliciesResult>
    <SearchHeader>
    ... snip


    This is what my REST controller method looks like:



    @PostMapping()
    public SearchPoliciesResponse searchRequest(@Valid @RequestBody SearchPoliciesRequest request)
    throws Exception {

    var allPoliciesFile = ResourceUtils.getFile("classpath:policies/search/policy-summary.xml");
    var jaxbContext = JAXBContext.newInstance(SearchPoliciesResponse.class);
    var jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    var response = (SearchPoliciesResponse) jaxbUnmarshaller.unmarshal(allPoliciesFile);

    // ... HERE I WILL MAKE SOME MANUAL CHANGES TO THE RESPONSE OBJECT

    return response;
    }


    I tried adding the following Bean to my configuration class (SpringBootApplication annotated class), but to no effect:



    @Bean
    public Jaxb2Marshaller marshaller() {
    var marshaller = new Jaxb2Marshaller();
    marshaller.setClassesToBeBound(SearchPoliciesResponse.class, SearchPoliciesRequest.class);

    return marshaller;
    }


    I know that the classes I use for (de)serialization are correctly annotated, because (a) they were autogenerated by JAXB (xjc tool), and (b) if I manually create a JAXBContext and marshall to XML, it's serialized correctly with the namespace I'm expecting.



    The policy classes package contains a package-info.java file with the correct QUALIFIED annotation on the package, so it should be working, and it is when done manually, for Spring.



    To test if the Spring marshaller bean I declared would work, I tested injecting it:



    @Autowired
    private Jaxb2Marshaller marshaller;


    And then tried marshalling manually



    var writer = new StringWriter();
    var result = new StringResult();
    marshaller.marshal(response, result);


    And it DID work fine. So it appears to be whatever happens between the REST controller return, and when Spring marshals the object, it's not using the Bean I declared.



    I'm using:



    springBootVersion = '2.0.4.RELEASE'
    org.springframework.ws:spring-ws-core:3.0.4.RELEASE



    I appreciate any hints.



    Thank you










    share|improve this question



























      0












      0








      0








      I'm trying to create a Spring REST WebService which will return a complex object to the caller. In particular this caller is going to be asking for the object using application/XML.



      Without any particular configuration about the marshaller, the object is serialized correctly to XML to the caller, BUT it does not contain XML namespace information, so the object deserialization fails on the caller side (I cannot change the caller's code, and don't want to either).



      This is the XML the client is receiving:



      <SearchPoliciesResponse>
      <searchPoliciesResult>
      <searchHeader>
      ... snip


      This is what they should be receiving:



      <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
      <SearchPoliciesResponse xmlns="http://com.cgic.app.service.policy/PolicySearch">
      <searchPoliciesResult>
      <SearchHeader>
      ... snip


      This is what my REST controller method looks like:



      @PostMapping()
      public SearchPoliciesResponse searchRequest(@Valid @RequestBody SearchPoliciesRequest request)
      throws Exception {

      var allPoliciesFile = ResourceUtils.getFile("classpath:policies/search/policy-summary.xml");
      var jaxbContext = JAXBContext.newInstance(SearchPoliciesResponse.class);
      var jaxbUnmarshaller = jaxbContext.createUnmarshaller();
      var response = (SearchPoliciesResponse) jaxbUnmarshaller.unmarshal(allPoliciesFile);

      // ... HERE I WILL MAKE SOME MANUAL CHANGES TO THE RESPONSE OBJECT

      return response;
      }


      I tried adding the following Bean to my configuration class (SpringBootApplication annotated class), but to no effect:



      @Bean
      public Jaxb2Marshaller marshaller() {
      var marshaller = new Jaxb2Marshaller();
      marshaller.setClassesToBeBound(SearchPoliciesResponse.class, SearchPoliciesRequest.class);

      return marshaller;
      }


      I know that the classes I use for (de)serialization are correctly annotated, because (a) they were autogenerated by JAXB (xjc tool), and (b) if I manually create a JAXBContext and marshall to XML, it's serialized correctly with the namespace I'm expecting.



      The policy classes package contains a package-info.java file with the correct QUALIFIED annotation on the package, so it should be working, and it is when done manually, for Spring.



      To test if the Spring marshaller bean I declared would work, I tested injecting it:



      @Autowired
      private Jaxb2Marshaller marshaller;


      And then tried marshalling manually



      var writer = new StringWriter();
      var result = new StringResult();
      marshaller.marshal(response, result);


      And it DID work fine. So it appears to be whatever happens between the REST controller return, and when Spring marshals the object, it's not using the Bean I declared.



      I'm using:



      springBootVersion = '2.0.4.RELEASE'
      org.springframework.ws:spring-ws-core:3.0.4.RELEASE



      I appreciate any hints.



      Thank you










      share|improve this question
















      I'm trying to create a Spring REST WebService which will return a complex object to the caller. In particular this caller is going to be asking for the object using application/XML.



      Without any particular configuration about the marshaller, the object is serialized correctly to XML to the caller, BUT it does not contain XML namespace information, so the object deserialization fails on the caller side (I cannot change the caller's code, and don't want to either).



      This is the XML the client is receiving:



      <SearchPoliciesResponse>
      <searchPoliciesResult>
      <searchHeader>
      ... snip


      This is what they should be receiving:



      <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
      <SearchPoliciesResponse xmlns="http://com.cgic.app.service.policy/PolicySearch">
      <searchPoliciesResult>
      <SearchHeader>
      ... snip


      This is what my REST controller method looks like:



      @PostMapping()
      public SearchPoliciesResponse searchRequest(@Valid @RequestBody SearchPoliciesRequest request)
      throws Exception {

      var allPoliciesFile = ResourceUtils.getFile("classpath:policies/search/policy-summary.xml");
      var jaxbContext = JAXBContext.newInstance(SearchPoliciesResponse.class);
      var jaxbUnmarshaller = jaxbContext.createUnmarshaller();
      var response = (SearchPoliciesResponse) jaxbUnmarshaller.unmarshal(allPoliciesFile);

      // ... HERE I WILL MAKE SOME MANUAL CHANGES TO THE RESPONSE OBJECT

      return response;
      }


      I tried adding the following Bean to my configuration class (SpringBootApplication annotated class), but to no effect:



      @Bean
      public Jaxb2Marshaller marshaller() {
      var marshaller = new Jaxb2Marshaller();
      marshaller.setClassesToBeBound(SearchPoliciesResponse.class, SearchPoliciesRequest.class);

      return marshaller;
      }


      I know that the classes I use for (de)serialization are correctly annotated, because (a) they were autogenerated by JAXB (xjc tool), and (b) if I manually create a JAXBContext and marshall to XML, it's serialized correctly with the namespace I'm expecting.



      The policy classes package contains a package-info.java file with the correct QUALIFIED annotation on the package, so it should be working, and it is when done manually, for Spring.



      To test if the Spring marshaller bean I declared would work, I tested injecting it:



      @Autowired
      private Jaxb2Marshaller marshaller;


      And then tried marshalling manually



      var writer = new StringWriter();
      var result = new StringResult();
      marshaller.marshal(response, result);


      And it DID work fine. So it appears to be whatever happens between the REST controller return, and when Spring marshals the object, it's not using the Bean I declared.



      I'm using:



      springBootVersion = '2.0.4.RELEASE'
      org.springframework.ws:spring-ws-core:3.0.4.RELEASE



      I appreciate any hints.



      Thank you







      java xml spring spring-boot






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 24 '18 at 2:54







      So Many Goblins

















      asked Nov 23 '18 at 14:08









      So Many GoblinsSo Many Goblins

      2,99973359




      2,99973359
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448198%2fconfiguring-xml-serializer-marshaller-in-spring-boot-application-rest-webservice%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448198%2fconfiguring-xml-serializer-marshaller-in-spring-boot-application-rest-webservice%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Wiesbaden

          Marschland

          Dieringhausen