使用java中的restTemplate将text/html解析为application/json

使用java中的restTemplate将text/html解析为application/json,java,spring-boot,rest,spring-mvc,Java,Spring Boot,Rest,Spring Mvc,这是我的密码: HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>(); map.add("xx

这是我的密码:

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
        map.add("xx","xx");
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
        ResponseEntity<String> response = new RestTemplate().postForEntity( url, request ,String.class);
HttpHeaders=newhttpheaders();
headers.setContentType(MediaType.APPLICATION\u FORM\u URLENCODED);
MultiValueMap=新链接的MultiValueMap();
地图。添加(“xx”、“xx”);
HttpEntity请求=新的HttpEntity(映射、头);
ResponseEntity response=new RestTemplate().postForEntity(url、请求、String.class);
以下是我的回应:

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <body onLoad="xx">
 <form action='xxx' method="post" name="aspForm" >
 <input type="hidden" name="responseMessage" value='Successfully Registered'/>
 <input type="hidden" name="url" value='xxxx'/>
 <input type="hidden" name="status" value='SUCCESS'/>
</form>
</body>
</html>


如何将这些名称和值对从html响应转换为JSON?

这可以使用Jsoup和Jackson对象映射器实现:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

Document doc = Jsoup.parse(html);
    
    String responseMessage = doc.body()
            .getElementsByAttributeValue("name", "responseMessage")
            .first()
            .attributes()
            .get("value");
    
    String status = doc.body()
            .getElementsByAttributeValue("name", "status")
            .first()
            .attributes()
            .get("value");
    
    String url = doc.body()
            .getElementsByAttributeValue("name", "url")
            .first()
            .attributes()
            .get("value");
    
    Response response = new Response();
    response.setResponseMessage(responseMessage);
    response.setStatus(status);
    response.setUrl(url);
    
    ObjectMapper mapper = new ObjectMapper();
    
    String json = mapper.writeValueAsString(response);
    
    System.out.println(json);
输出:

{"responseMessage":"Successfully Registered","status":"SUCCESS","url":"xxxx"}
更新:

如果需要转换HTML字符串而不需要手动webscraping,也可以(但我认为它只适用于XHTML,因为解析器会破坏不符合XML的标记)

POM相关性:

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.moxy</artifactId>
    <version>2.5.2</version>
    <type>jar</type>
 </dependency>
创建消息转换器:

private static HttpMessageConverter<Object> createXmlHttpMessageConverter() throws JAXBException {
    MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
   // I added lot of mediatypes, leave necessary ones
    xmlConverter.setSupportedMediaTypes(Arrays.asList(
            MediaType.APPLICATION_XML, MediaType.TEXT_HTML, MediaType.TEXT_PLAIN, MediaType.TEXT_XML
    ));
    Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setClassesToBeBound(Response.class);
    // without this jaxb will complain about doctype in the beginning
    jaxb2Marshaller.setSupportDtd(true);
    xmlConverter.setMarshaller(jaxb2Marshaller);
    xmlConverter.setUnmarshaller(jaxb2Marshaller);
    return xmlConverter;
}
您还需要将MOXy设置为JAXB提供程序。我使用这个代码

System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, "org.eclipse.persistence.jaxb.JAXBContextFactory");
但这也可以通过其他方式实现

这一切都将允许您执行呼叫:

Response response = rest.postForEntity(url, request, Response.class);

从响应实例中,使用Jackson检索JSON应该很简单。

这可以通过使用Jsoup和Jackson对象映射器实现:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

Document doc = Jsoup.parse(html);
    
    String responseMessage = doc.body()
            .getElementsByAttributeValue("name", "responseMessage")
            .first()
            .attributes()
            .get("value");
    
    String status = doc.body()
            .getElementsByAttributeValue("name", "status")
            .first()
            .attributes()
            .get("value");
    
    String url = doc.body()
            .getElementsByAttributeValue("name", "url")
            .first()
            .attributes()
            .get("value");
    
    Response response = new Response();
    response.setResponseMessage(responseMessage);
    response.setStatus(status);
    response.setUrl(url);
    
    ObjectMapper mapper = new ObjectMapper();
    
    String json = mapper.writeValueAsString(response);
    
    System.out.println(json);
输出:

{"responseMessage":"Successfully Registered","status":"SUCCESS","url":"xxxx"}
更新:

如果需要转换HTML字符串而不需要手动webscraping,也可以(但我认为它只适用于XHTML,因为解析器会破坏不符合XML的标记)

POM相关性:

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.moxy</artifactId>
    <version>2.5.2</version>
    <type>jar</type>
 </dependency>
创建消息转换器:

private static HttpMessageConverter<Object> createXmlHttpMessageConverter() throws JAXBException {
    MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
   // I added lot of mediatypes, leave necessary ones
    xmlConverter.setSupportedMediaTypes(Arrays.asList(
            MediaType.APPLICATION_XML, MediaType.TEXT_HTML, MediaType.TEXT_PLAIN, MediaType.TEXT_XML
    ));
    Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setClassesToBeBound(Response.class);
    // without this jaxb will complain about doctype in the beginning
    jaxb2Marshaller.setSupportDtd(true);
    xmlConverter.setMarshaller(jaxb2Marshaller);
    xmlConverter.setUnmarshaller(jaxb2Marshaller);
    return xmlConverter;
}
您还需要将MOXy设置为JAXB提供程序。我使用这个代码

System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, "org.eclipse.persistence.jaxb.JAXBContextFactory");
但这也可以通过其他方式实现

这一切都将允许您执行呼叫:

Response response = rest.postForEntity(url, request, Response.class);

从响应实例中,使用Jackson检索JSON应该很简单。

为什么不在服务中进行更改以返回JSON而不是HTML呢?为了完全理解这里的目标,在解释中有点“精简”。如果您试图将一个JSON
字符串
.html
页面发送回您所连接的服务器,那么关于将JSON从客户端发送到服务器,有数百种答案。对不起,我希望我没有听起来粗鲁,不是我的本意。。。我无法准确地说出您的数据需要转换的部分(和位置)。亲爱的Alien,当我使用上面的表单url编码点击第三方API时,我得到了上面指定的html响应。我需要使用响应并需要执行一些业务操作。希望您现在明白了。亲爱的@Y2020-09,下面给出的解决方案就是我正在寻找的解决方案。您为什么不在服务中进行更改以返回json而不是HTMLT呢?这在解释中有点“lite”,以便完全理解这里的目标。如果您试图将一个JSON
字符串
.html
页面发送回您所连接的服务器,那么关于将JSON从客户端发送到服务器,有数百种答案。对不起,我希望我没有听起来粗鲁,不是我的本意。。。我无法准确地说出您的数据需要转换的部分(和位置)。亲爱的Alien,当我使用上面的表单url编码点击第三方API时,我得到了上面指定的html响应。我需要使用响应并需要执行一些业务操作。希望你现在明白了。亲爱的@Y2020-09,下面给出的解决方案就是我正在寻找的。是的,Alexandra,我同意你的答案。我们也可以通过使用HtmlUnit框架的HtmlPage对象来实现这一点。你提供的代码只不过是“废话”。有没有其他方法可以捕获从API到JSON的HTML响应?谢谢:)另一个解决方案的更新答案我们非常感谢您的努力。。谢谢你,我的朋友…-)是的,亚历山德拉,我同意你的回答。我们也可以通过使用HtmlUnit框架的HtmlPage对象来实现这一点。你提供的代码只不过是“废话”。有没有其他方法可以捕获从API到JSON的HTML响应?谢谢:)另一个解决方案的更新答案我们非常感谢您的努力。。谢谢你,我的朋友…-)