spring 如何将XML响应从Roku Tv API转换为JSON?

yftpprvb  于 2023-11-16  发布在  Spring
关注(0)|答案(1)|浏览(116)

我试图构建一个使用Roku Tv ECP API命令的应用程序。我试图进行的特定调用获取所有已安装频道的列表,并以XML格式返回。每当我调用此API时,在提取响应时都会收到错误。
下面是我如何进行API调用:

public class ConsumeXMLResponse {

        private RestTemplate restTemplate;

        private final Logger log = LoggerFactory.getLogger(ConsumeXMLResponse.class);

        public ConsumeXMLResponse(RestTemplate restTemplate) {
            this.restTemplate = restTemplate;
        }

        public ResponseEntity<Apps> get() {
            this.restTemplate = new RestTemplateBuilder().build();
            List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
            MappingJackson2HttpMessageConverter converter = new              MappingJackson2HttpMessageConverter();
            converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
            messageConverters.add(converter);
            this.restTemplate.setMessageConverters(messageConverters);

            log.info("This worked!");
            return this.restTemplate.getForEntity("http://10.0.0.229:8060/query/apps",
                    Apps.class);

        }

    }

个字符
我试图从响应中重新创建的对象:

@XmlRootElement(name = "apps")
@XmlAccessorType(XmlAccessType.FIELD)
public class Apps {

    @XmlElement(name = "app")
    private List<App> app;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class App {

    @XmlAttribute(name = "id")
    public String id;

    @XmlAttribute(name = "type")
    public String type;

    @XmlAttribute(name = "version")
    public String version;

}

的字符串
下面是在postman中直接调用API时XML的示例:

<?xml version="1.0" encoding="UTF-8" ?>
<apps>
    <app id="tvinput.hdmi3" type="tvin" version="1.0.0">firestick</app>
    <app id="tvinput.hdmi1" type="tvin" version="1.0.0">Xbox</app>
    <app id="tvinput.hdmi2" type="tvin" version="1.0.0">Nintendo Switch</app>
    <app id="tvinput.dtv" type="tvin" version="1.0.0">Live TV</app>
    <app id="12" type="appl" version="5.1.120088002">Netflix</app>
    <app id="61322" type="appl" version="55.2.0">Max</app>
    <app id="13" type="appl" version="14.1.2023092022">Prime Video</app>
    <app id="2285" type="appl" version="6.75.2">Hulu</app>
    <app id="291097" type="appl" version="1.37.2023101000">Disney Plus</app>
    <app id="34376" type="appl" version="4.8.2023051800">ESPN</app>
    <app id="151908" type="appl" version="9.3.10">The Roku Channel</app>
    <app id="13842" type="appl" version="1.1.9">Vudu</app>
    <app id="46041" type="appl" version="8.96.12089">Sling TV - Live Sports, News, Shows + Freestream</app>
    <app id="45706" type="appl" version="1.0.60">Roku TV Intro</app>
    <app id="552944" type="appl" version="1.2.64">Roku Tips &amp; Tricks</app>
    <app id="562661" type="appl" version="1.2.28">Zoom TV for Kids</app>
    <app id="86398" type="appl" version="9.4.0">SYFY</app>
    <app id="593099" type="appl" version="4.11.12">Peacock TV</app>
    <app id="41468" type="appl" version="3.0.2">Tubi - Free Movies &amp; TV</app>
    <app id="31440" type="appl" version="8.8.202310302">Paramount Plus</app>
    <app id="dev" type="appl" version="1.0.1">MovieBoxPro</app>
</apps>


我尝试调用返回XML响应的API,然后将其转换为Map到Apps类的Java对象。
这是一个错误:

2023-11-06T17:06:46.430-05:00 ERROR 76726 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.web.client.RestClientException: Error while extracting response for type [class com.TelevisionRemote.SmartTelevisionRemote.component.Apps] and content type [text/xml;charset="utf-8"]] with root cause

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2]
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2418) ~[jackson-core-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:749) ~[jackson-core-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:673) ~[jackson-core-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2784) ~[jackson-core-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:907) ~[jackson-core-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:793) ~[jackson-core-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.databind.ObjectReader._initForReading(ObjectReader.java:357) ~[jackson-databind-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2095) ~[jackson-databind-2.14.2.jar:2.14.2]
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1481) ~[jackson-databind-2.14.2.jar:2.14.2]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:395) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:354) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:103) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1132) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1115) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:865) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:764) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:405) ~[spring-web-6.0.6.jar:6.0.6]
    at com.TelevisionRemote.SmartTelevisionRemote.controller.ConsumeXMLResponse.get(ConsumeXMLResponse.java:38) ~[classes/:na]
    at com.TelevisionRemote.SmartTelevisionRemote.controller.RestXMLResponseController.getXMLOutput(RestXMLResponseController.java:28) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:705) ~[tomcat-embed-core-10.1.5.jar:6.0]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.6.jar:6.0.6]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[tomcat-embed-core-10.1.5.jar:6.0]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.6.jar:6.0.6]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.6.jar:6.0.6]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.6.jar:6.0.6]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.6.jar:6.0.6]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
    at java.base/java.lang.Thread.run(Thread.java:1623) ~[na:na]

iaqfqrcu

iaqfqrcu1#

事实证明,将@JacksonXmlElementWrapper添加到我的应用程序列表属性上的Apps类解决了这个问题。

@JacksonXmlElementWrapper(useWrapping = false)
private List<App> app;

字符串
我也不需要消息转换器。

public Apps getXMLOutput() {

    ResponseEntity<Apps> responseEntity
            = this.restTemplate.getForEntity("http://10.0.0.229:8060/query/apps",
            Apps.class);

    Apps apps = responseEntity.getBody();

    log.info(apps.toString());
    return appsRepository.save(apps);
}


Postman中的结果:

{
    "id": 1,
    "app": [
        {
            "id": "tvinput.hdmi3",
            "type": "tvin",
            "version": "1.0.0"
        },
        {
            "id": "tvinput.hdmi1",
            "type": "tvin",
            "version": "1.0.0"
        },
        {
            "id": "tvinput.hdmi2",
            "type": "tvin",
            "version": "1.0.0"
        },
        {
            "id": "tvinput.dtv",
            "type": "tvin",
            "version": "1.0.0"
        },
        {
            "id": "12",
            "type": "appl",
            "version": "5.1.120088002"
        },
        {
            "id": "61322",
            "type": "appl",
            "version": "55.2.0"
        },
        {
            "id": "13",
            "type": "appl",
            "version": "14.1.2023092022"
        },
        {
            "id": "2285",
            "type": "appl",
            "version": "6.75.2"
        },
        {
            "id": "291097",
            "type": "appl",
            "version": "1.37.2023101000"
        },
        {
            "id": "34376",
            "type": "appl",
            "version": "4.8.2023051800"
        },
        {
            "id": "151908",
            "type": "appl",
            "version": "9.3.10"
        },
        {
            "id": "13842",
            "type": "appl",
            "version": "1.1.9"
        },
        {
            "id": "46041",
            "type": "appl",
            "version": "8.97.12290"
        },
        {
            "id": "45706",
            "type": "appl",
            "version": "1.0.60"
        },
        {
            "id": "552944",
            "type": "appl",
            "version": "1.2.64"
        },
        {
            "id": "562661",
            "type": "appl",
            "version": "1.2.28"
        },
        {
            "id": "86398",
            "type": "appl",
            "version": "9.4.0"
        },
        {
            "id": "593099",
            "type": "appl",
            "version": "4.11.12"
        },
        {
            "id": "41468",
            "type": "appl",
            "version": "3.0.2"
        },
        {
            "id": "31440",
            "type": "appl",
            "version": "8.8.202310302"
        },
        {
            "id": "dev",
            "type": "appl",
            "version": "1.0.1"
        }
    ]
}

相关问题