如何创建网站老鱼网,甘肃省住房和建设厅官方网站,搜索引擎优化策略不包括,公司网络组建方案怎么写文章目录 1.问题描述2.问题分析3.问题解决3.1 Apache HttpClient 依赖3.2 RestTemplate 配置类3.3 测试 1.问题描述 直接通过浏览器访问请求没有问题#xff0c;但是通过 RestTemplate 访问请求却会出现乱码问题。 2.问题分析
首先我认为是 SpringBoot 版本、JDK 版本、项目结… 文章目录 1.问题描述2.问题分析3.问题解决3.1 Apache HttpClient 依赖3.2 RestTemplate 配置类3.3 测试 1.问题描述 直接通过浏览器访问请求没有问题但是通过 RestTemplate 访问请求却会出现乱码问题。 2.问题分析
首先我认为是 SpringBoot 版本、JDK 版本、项目结构配置的问题但是即使我进行更新也没有效果。
然后再想的是默认注入的 RestTemplate 是不是内置的字符编码有问题。
于是我 Debug 查看 RestTemplate 的配置流程。 而该请求响应的 content-type 为 application/json;charsetutf-8
因此我猜测是字符编码的问题于是我需要重新设置一下默认的字符编码。
/*** 通过 RestTemplate,我们可以发出 http 请求(支持 Restful 风格),* 去调用 Controller 提供的 API 接口, 就像我们使用浏览器发出 http 请求, 调用该 API 接口一样** author 狐狸半面添* create 2024-03-29 0:30*/
Configuration
public class RestTemplateConfig {/*** 配置注入 RestTemplate bean/对象** return 实例对象*/Beanpublic RestTemplate restTemplate() {RestTemplate restTemplate new RestTemplate();// 对所有 RestTemplate 的消息转换器进行遍历restTemplate.getMessageConverters().forEach(httpMessageConverter - {// 找到 httpMessageConverter修改默认的字符编码if (httpMessageConverter instanceof StringHttpMessageConverter) {((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(java.nio.charset.StandardCharsets.UTF_8);}});return restTemplate;}
}但遗憾的是还是没有用。再结合我之前使用 RestTemplate 的经历也没有去设置过 DefaultCharset因此我觉得应该本来就不需要设置RestTemplate 在获取到响应数据后会解析到 content-type 中的 charsetutf-8 从而按照声明的 utf-8 字符集进行解码处理。
在最后呢我结合着浏览器可以正常响应数据而 RestTemplate 不可以出现了乱码以及我观察到响应头的一个字段 Content-Encoding: gzip。因此我猜测是不是请求 URL 对应的服务器已经对数据进行了 gzip 压缩而导致的 RestTemplate 显示乱码。至于浏览器为什么能正常解析这是因为浏览器已经对响应数据做了处理才进行的显示浏览器发现 Content-Encoding: gzip 就对数据进行了解压缩。
那 RestTemplate 如何处理经过 gzip 压缩后的响应数据呢那我们就需要借助 Apache HttpClient 的功能来处理 Gzip 压缩的响应。
原理当 RestTemplate 接收到经过 Gzip 压缩的响应时底层的 HTTP 客户端库会自动解压缩这个响应然后将解压缩后的内容传递给 RestTemplate 进行处理。
3.问题解决
3.1 Apache HttpClient 依赖
dependencygroupIdorg.apache.httpcomponents/groupIdartifactIdhttpclient/artifactIdversion4.5.13/version
/dependency3.2 RestTemplate 配置类
import org.apache.http.impl.client.HttpClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;/*** 通过 RestTemplate,我们可以发出 http 请求(支持 Restful 风格),* 去调用 Controller 提供的 API 接口, 就像我们使用浏览器发出 http 请求, 调用该 API 接口一样** author 狐狸半面添* create 2023-02-17 1:43*/
Configuration
public class RestTemplateConfig {/*** 配置注入 RestTemplate bean/对象** return 实例对象*/Beanpublic RestTemplate restTemplate() {// 加入 Apache HttpClient 的功能HttpComponentsClientHttpRequestFactory factory new HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());RestTemplate restTemplate new RestTemplate(factory);// 这里也可以不注释// restTemplate.getMessageConverters().forEach(httpMessageConverter - {// if (httpMessageConverter instanceof StringHttpMessageConverter) {// ((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(java.nio.charset.StandardCharsets.UTF_8);// }// });return restTemplate;}
}3.3 测试
RestController
public class WeatherController {/*** 这里你需要根据自己的业务进行配置*/private final static String apiKey **************************************;/*** 访问风和天气 url 的访问格式* {} 表示占位符*/private final static String URL https://geoapi.qweather.com/v2/city/lookup?location{cityName}key{apiKey};Resourceprivate RestTemplate restTemplate;/*** 根据用户输入的城市查询城市天气* 请求示例http://localhost:8080/city/长沙** param cityName* return*/GetMapping(/city/{cityName})public String getWeatherByCityName(PathVariable(cityName) String cityName) {// 方式一// String url URL cityName key apiKey;// ResponseEntityString responseEntity restTemplate.getForEntity(URL, String.class);// 方式二// public T ResponseEntityT getForEntity(String url, ClassT responseType, Object... uriVariables)// 相应数据格式是 application/json; charsetutf-8// 如果你需要做额外数据处理可以先将响应的 json 数据转为 bean 做进一步处理// 例如JSON.parseObject(responseEntity.getBody(), ClassT objectClass)ResponseEntityString responseEntity restTemplate.getForEntity(URL, String.class, cityName, apiKey);return responseEntity.getBody();}}