2017-02-03 10 views
0

Я портирую старое приложение, которое работает на JBoss для Spring Boot/Tomcat, и у вас есть все, что работает, кроме ответа XML. Старый код, похоже, использует xmlbeans для генерации источника XSD. Я изменил это, чтобы использовать JAXB. Вот мой класс:Класс JAXB вернулся из элементов XMLRestController XML

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "EventsResponseType1_1", propOrder = { 
    "getAllEventCodesResponse", 
    "saveEventCodeResponse", 
    "failMessageResponse", 
    "getEmailHistoryResponse" 
}) 
public class EventsResponseType11 { 

    protected GetAllEventCodesResponseType getAllEventCodesResponse; 
    protected SaveEventCodeResponseType saveEventCodeResponse; 
    @XmlElement(name = "FailMessageResponse") 
    protected ResponseType failMessageResponse; 
    protected GetEmailHistoryResponseType getEmailHistoryResponse; 

    // Getters and setters 
} 

И один из классов элементов:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "getAllEventCodesResponseType", propOrder = { 
    "_return", 
    "results" 
}) 
public class GetAllEventCodesResponseType { 

    @XmlElement(name = "Return", required = true) 
    protected ReturnType _return; 
    @XmlElement(name = "Results") 
    protected GetAllEventCodesResponseType.Results results; 

    // Getters and setters 
} 

Вот ответ XML:

<com.foo.bar.EventsResponseType11> 
    <getAllEventCodesResponse> 
     <__return> 
     <returnCode>0</returnCode> 
     <returnMessage /> 
     </__return> 
     <results> 
     <eventCodes> 
      <com.foo.bar.EventCodeInfoType> 
       <eventCodeID>1</eventCodeID> 
       <eventCode>1000</eventCode> 
       <eventCodeDesc>Success</eventCodeDesc> 
       <eventCodeIndicator>SUCCESS</eventCodeIndicator> 
       <eventCodeContext>General</eventCodeContext> 
       <createdBy>system</createdBy> 
      </com.foo.bar.EventCodeInfoType> 
     </eventCodes> 
     </results> 
    </getAllEventCodesResponse> 
</com.foo.bar.EventsResponseType11> 

Я настроил мое приложение:

@SpringBootApplication 
@ComponentScan("com.foo.bar") 
public class WsApp extends WebMvcConfigurerAdapter{ 

    public static void main(String[] args) { 
     SpringApplication.run(WsApp.class, args); 
    } 

    /** 
    * Configure the XML as the only return type on requests 
    */ 
    @Override 
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 

     List<MediaType> mediaTypes = new ArrayList<>(); 
     mediaTypes.add(MediaType.TEXT_XML); 

     XStreamMarshaller xmlMarshaller = new XStreamMarshaller(); 

     MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(xmlMarshaller); 
     xmlConverter.setSupportedMediaTypes(mediaTypes); 

     converters.add(xmlConverter); 

     super.configureMessageConverters(converters); 
    } 
} 

И мой контроллер:

@RestController 
@RequestMapping("/go") 
public class EventService { 
    @RequestMapping(value = "/events", method = RequestMethod.POST) 
    public ResponseEntity<EventsResponseType11> events(@RequestBody EventsRequestType11 request){ 

     EventsResponseType11 responseDoc = eventCodesProxy.invoke(request); 

     return ResponseEntity.ok(responseDoc); 
    } 
} 

Итак, мой первый вопрос: как я могу остановить маршаллера от включения имени пакета для тех элементов, которые его имеют.

И, во-вторых, поскольку XSD определяет поле как «возвращаемое», JAXB добавил символ подчеркивания к имени поля. Аннотация @XmlElement в этом поле идентифицирует это как «Возврат», который я хочу получить от ответа (без каких-либо подчеркиваний).

Я попытался использовать JAXB Marshaller вместо XStreamMarshaller без везения. Если это вообще возможно, я бы предпочел не изменять схему, потому что она старая и имеет много межсегментных зависимостей.

Заранее благодарим за вашу помощь!

+0

Для начала прекратите использование 'XStreamMarshaller', поскольку это ничего не делает с аннотациями JAXB. То, что вы сейчас видите, в основном является поведением XStream по умолчанию. Вместо этого вы должны использовать маршаллер JAXB. –

+0

Хотя это имеет смысл, я пробовал этот подход с сомнительными результатами. Я заменил маршаллера XStream на 'Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();' \t 'jaxb2Marshaller.setPackagesToScan (« com.xsd.package »);' и теперь служба возвращает JSON. Зачем? Поскольку я настроил свой конвертер сообщений для возврата ТОЛЬКО XML, я бы этого не ожидал. Также я добавил '@ XmlRootElement' к моему объекту верхнего уровня' EventsResponseType11' без везения. –

+0

То, что возвращается, зависит от запроса и запрошенного типа возврата. Вы не должны изменять сгенерированные классы, как в следующий раз, когда они снова исчезнут, и вы забудете их добавить. Просто заверните результат в 'JAXBElement' вместо того, чтобы возвращать обычный« EventResponseType11 »вместо' JAXBElement 'вместо этого. Существует метод для созданного объекта ObjectFactory, который может сделать это для вас. –

ответ

0

Таким образом, после многих проб и ошибок, я наткнулся на этот пост:

Spring 4 mvc REST XML and JSON response

Мой класс приложения:

@SpringBootApplication 
@ComponentScan("com.foo.bar") 
@EnableWebMvc 
public class WsApp extends WebMvcConfigurerAdapter{ 

    public static void main(String[] args) { 
     SpringApplication.run(WsApp.class, args); 
    } 

    /** 
    * Configure the negotiator to return ONLY XML 
    */ 
    @Override 
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
     configurer.favorPathExtension(false). 
      favorParameter(true). 
      parameterName("mediaType"). 
      ignoreAcceptHeader(true). 
      useJaf(false). 
      defaultContentType(MediaType.APPLICATION_XML). 
      mediaType("xml", MediaType.APPLICATION_XML); 
    } 
} 

я уже говорил, что я не был бы счастлив о модификации XSD, но мне пришлось сделать несколько настроек, чтобы добавить @XmlRootElement. Я попытался изменить генерацию источника JAXB через дополнительные библиотеки, но это не получилось так хорошо.

Смежные вопросы