如何将我的 XML 响应从 Roku Tv api 转换为 JSON?

问题描述 投票:0回答:1

我正在尝试构建一个使用 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);

        }

    }
@Controller
@RequestMapping("View")
public class RestXMLResponseController {

    private RestTemplate restTemplate;

    // Annotation
    @GetMapping(path = "/get", produces = {"application/xml"})
    public String
    getXMLOutput(Model model)
    {

        ConsumeXMLResponse response
                = new ConsumeXMLResponse(restTemplate);
        ResponseEntity<Apps> responseEntity
                = response.get();

        //Apps entity = responseEntity.getBody();
        //HttpHeaders headers = responseEntity.getHeaders();

        //model.addAttribute("xml", entity);
        //model.addAttribute("XMLheaders", headers);

        return "View";
    }

}

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

@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,然后将其转换为映射到 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]

json xml spring spring-boot roku
1个回答
0
投票

事实证明,将 @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);
}

邮递员中的结果:

{ “id”:1, “应用程序”: [ { "id": "tvinput.hdmi3", “类型”:“电视”, “版本”:“1.0.0” }, { "id": "tvinput.hdmi1", “类型”:“电视”, “版本”:“1.0.0” }, { "id": "tvinput.hdmi2", “类型”:“电视”, “版本”:“1.0.0” }, { "id": "tvinput.dtv", “类型”:“电视”, “版本”:“1.0.0” }, { “id”:“12”, “类型”:“应用程序”, “版本”:“5.1.120088002” }, { “id”:“61322”, “类型”:“应用程序”, “版本”:“55.2.0” }, { “id”:“13”, “类型”:“应用程序”, “版本”:“14.1.2023092022” }, { “id”:“2285”, “类型”:“应用程序”, “版本”:“6.75.2” }, { “id”:“291097”, “类型”:“应用程序”, “版本”:“1.37.2023101000” }, { “id”:“34376”, “类型”:“应用程序”, “版本”:“4.8.2023051800” }, { “id”:“151908”, “类型”:“应用程序”, “版本”:“9.3.10” }, { “id”:“13842”, “类型”:“应用程序”, “版本”:“1.1.9” }, { “id”:“46041”, “类型”:“应用程序”, “版本”:“8.97.12290” }, { “id”:“45706”, “类型”:“应用程序”, “版本”:“1.0.60” }, { “id”:“552944”, “类型”:“应用程序”, “版本”:“1.2.64” }, { “id”:“562661”, “类型”:“应用程序”, “版本”:“1.2.28” }, { “id”:“86398”, “类型”:“应用程序”, “版本”:“9.4.0” }, { “id”:“593099”, “类型”:“应用程序”, “版本”:“12.11.4” }, { “id”:“41468”, “类型”:“应用程序”, “版本”:“3.0.2” }, { “id”:“31440”, “类型”:“应用程序”, “版本”:“8.8.202310302” }, { “id”:“开发”, “类型”:“应用程序”, “版本”:“1.0.1” } ] }

© www.soinside.com 2019 - 2024. All rights reserved.