Spring Boot中RestTemplate getForObject响应解码异常问题排查
解决RestTemplate GET请求响应乱码问题
以下是几种优先级递进的解决方案,可逐一尝试:
1. 替换默认StringHttpMessageConverter而非添加
你当前是新增UTF-8编码的转换器到首位,但RestTemplate默认已内置该转换器,新增操作可能未覆盖原有配置。正确做法是替换原有转换器:
RestTemplate restTemplate = new RestTemplate(); // 移除默认的StringHttpMessageConverter实例 restTemplate.getMessageConverters().removeIf(converter -> converter instanceof StringHttpMessageConverter); // 添加指定UTF-8编码的转换器 restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); String response = restTemplate.getForObject(url, String.class);
2. 处理响应压缩(gzip/deflate)
Postman会自动解压压缩响应,但RestTemplate默认不支持。若服务器返回gzip或deflate格式的响应,直接读取会出现乱码,需添加解压逻辑:
RestTemplate restTemplate = new RestTemplate(); // 配置请求头告知服务器接受压缩响应,并自动处理解压 List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(); interceptors.add((request, body, execution) -> { request.getHeaders().add("Accept-Encoding", "gzip, deflate"); ClientHttpResponse response = execution.execute(request, body); String encoding = response.getHeaders().getFirst("Content-Encoding"); if ("gzip".equals(encoding)) { return new GzipClientHttpResponse(response); } else if ("deflate".equals(encoding)) { return new DeflateClientHttpResponse(response); } return response; }); restTemplate.setInterceptors(interceptors); // 同时配置UTF-8消息转换器 restTemplate.getMessageConverters().removeIf(converter -> converter instanceof StringHttpMessageConverter); restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); String response = restTemplate.getForObject(url, String.class);
注:GzipClientHttpResponse和DeflateClientHttpResponse是Spring框架内置类,确保项目依赖完整即可使用。
3. 手动读取响应流并指定编码
若上述方法无效,可直接获取响应资源,手动从输入流读取内容并强制指定UTF-8编码:
RestTemplate restTemplate = new RestTemplate(); ResponseEntity<Resource> responseEntity = restTemplate.getForEntity(url, Resource.class); // 从响应流中读取字节并转成UTF-8编码的字符串 String response = new String(responseEntity.getBody().getInputStream().readAllBytes(), StandardCharsets.UTF_8);
4. 强制指定媒体类型的解码编码
若服务器返回的Content-Type头未明确标注编码(如仅返回text/plain而非text/plain;charset=UTF-8),可自定义消息转换器,强制所有文本类媒体类型使用UTF-8解码:
RestTemplate restTemplate = new RestTemplate(); StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8); // 设置支持的媒体类型列表,覆盖默认编码逻辑 List<MediaType> supportedMediaTypes = Arrays.asList( MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED ); stringConverter.setSupportedMediaTypes(supportedMediaTypes); // 替换原有转换器 restTemplate.getMessageConverters().removeIf(converter -> converter instanceof StringHttpMessageConverter); restTemplate.getMessageConverters().add(stringConverter); String response = restTemplate.getForObject(url, String.class);
内容的提问来源于stack exchange,提问作者P D
相关产品推荐
相关产品推荐

