失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > springboot 设置全局字符编码 解决乱码问题

springboot 设置全局字符编码 解决乱码问题

时间:2021-08-14 18:20:43

相关推荐

springboot 设置全局字符编码 解决乱码问题

设置springboot字符编码,只是设置http请求HttpServletRequest和响应HttpServletResponse的报文编码格式。

请求编码格式是告诉我们用什么编码解析入参,请求头中的设置的编码格式(content-type=“application/json; charset=GBK”),优先级高于HttpServletRequest的编码格式,如果请求头没设置,默认使用HttpServletRequest中的。

响应编码格式只是告诉别人接收到你返回的数据时,使用什么编码格式去转换二进制流(解析数据)。与项目运行的编码格式无关,项目运行的编码格式是在idea中设置的项目编码格式,或者启动项目是的运行参数设置。http编码格式和项目编码格式不同时,就可能返回乱码数据。假如项目运行使用的utf-8,而http设置的为返回gbk格式,此时返回的数据(中文)就是utf-8转成gbk格式的乱码。

编码格式其实是对于字节而言的,字符串其实不存在字符编码问题。乱码是在字符串转字节,然后字节转字符串时出现的,前后编码格式保持一致无论使用哪种编码格式都不会乱码

以下方法都可以设置请求和响应的字符编码格式

优先级:方法一 < 方法二 < 方法三

方法一:

springboot默认的编码格式就是UTF-8(只有request是),可以在HttpEncodingAutoConfiguration和HttpEncodingProperties(HttpProperties )这两个类中查看。如果不设置HttpServletRequest默认是utf-8格式,HttpServletResponse默认iso-8859-1,可通过response.getCharacterEncoding()方法查看。

#全局编码格式 请求和响应同时设置,也可以单独设置,可以看一下源码的属性spring.http.encoding.force=truespring.http.encoding.charset=UTF-8spring.http.encoding.enabled=trueserver.tomcat.uri-encoding=UTF-8

方法二:

这个方法可以解决NO converter for [xxxx] with preset Content-Type ‘null‘的问题,也可设置字符编码。设置字符编码时不会影响接口HttpServletRequest request,HttpServletResponse response的编码格式,但在过滤器中会改变ServletResponse的编码格式(ServletRequest编码也未改变)。~~只是在返回报文的时候使用指定的编码格式化,优先级高于方法一~~ 这个方法可能由于config.setSerializerFeatures设置的值较少,在使用时使用postman工具调用接口正常(postman发送报文使用的编码格式应该是UTF-8,将请求头中编码格式设置成其他,项目在解析参数时会出现乱码),但第三方请求接口是报400异常,接口获取不到请求体,可能是解析出了问题.....后来没有深究

/*** json序列化配置类*/@Configurationpublic class JsonHttpMessageConfiguration{/*** 配置全局序列化的时候为null的属性也序列化*/@Bean@ConditionalOnMissingBean(FastJsonHttpMessageConverter.class)public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {//1.需要定义一个convert转换消息的对象FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();//2.添加fastJson的配置信息;FastJsonConfig config = new FastJsonConfig();//添加配置-config.setSerializerFeatures() 方法中可以添加多个配置(以,分开)config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect);//3.在convert中添加配置信息.// 配置全局支持的媒体类型converter.setSupportedMediaTypes(getSupportedMediaTypes());converter.setFastJsonConfig(config);//设置字符编码converter.setDefaultCharset(Charset.forName("GBK"));return converter;}/*** 配置全局支持的媒体类型*/private List<MediaType> getSupportedMediaTypes() {List<MediaType> supportedMediaTypes = new ArrayList<>();//supportedMediaTypes.add(MediaType.ALL);supportedMediaTypes.add(MediaType.APPLICATION_JSON);supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);supportedMediaTypes.add(MediaType.APPLICATION_PDF);supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);supportedMediaTypes.add(MediaType.APPLICATION_XML);supportedMediaTypes.add(MediaType.IMAGE_GIF);supportedMediaTypes.add(MediaType.IMAGE_JPEG);supportedMediaTypes.add(MediaType.IMAGE_PNG);supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);supportedMediaTypes.add(MediaType.TEXT_HTML);supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);supportedMediaTypes.add(MediaType.TEXT_PLAIN);supportedMediaTypes.add(MediaType.TEXT_XML);return supportedMediaTypes;}}

方法三:

使用RequestMapping注解属性设置,设置字符编码时也不会影响接口参数中HttpServletRequest request,HttpServletResponse response的编码格式,但在过滤器中会改变ServletResponse的编码格式(ServletRequest编码也未改变)。此方法会出现NO converter for [xxxx] with preset Content-Type ‘null‘的问题(可能版本原因)需要配合方法二使用。也可以在接口中直接赋值,这种方法在过滤器中会改变ServletResponse、ServletRequest的编码格式,不用和方法二配合使用。

@RequestMapping(value = "/notify",headers ={"Content-Type=application/x-www-form-urlencoded;charset=GBK"} , method = RequestMethod.POST, consumer= "application/json; charset=GBK",produces = "application/json; charset=GBK")// GBK 只是告诉别人接收返回的数据时,使用GBK编码格式化字节数据,如果项目使用的utf-8格式,则返回的字节数组是utf-8格式的,这里指定GBK,别人在解析接收数据时就会乱码,所以这里指定的编码格式要与项目使用的编码一值public ResponseEntity<String> notify(@RequestParam(name = "p") String plain, @RequestParam("s") String signature), HttpServletRequest request,HttpServletResponse response){request.setCharacterEncoding("GBK");response.setCharacterEncoding("GBK");//与produces 设置相同,优先级低于produces response.setContentType("application/json;charset=GBK");//3设置

方法四:

自定义过滤器等等,原理类似

@Configurationpublic class CharacterConfig {@Beanpublic FilterRegistrationBean filterRegistrationBean(){//创建SpringWeb提供的字符编码过滤器,主要实现字符编码过滤CharacterEncodingFilter filter = new CharacterEncodingFilter();filter.setForceEncoding(true);//强制对请求的编码,filter.setEncoding("GBK");//使用GBK编码FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(filter);filterRegistrationBean.addUrlPatterns("/*");return filterRegistrationBean;}//@Bean//CharacterEncodingFilter characterEncodingFilter() {//CharacterEncodingFilter filter = new CharacterEncodingFilter();//filter.setEncoding("UTF-8");//filter.setForceEncoding(true);//return filter;//}}

自定义filter 处理请求和响应数据

package com.hoau.monitor.filter;import com.alibaba.dubbo.config.annotation.Reference;import com.alibaba.fastjson.JSONObject;import mon.exception.PSBCommonException;import com.hoau.monitor.entity.MonitorData;import com.hoau.monitor.facade.IhoauMonitorDataFacade;import com.hoau.monitor.servlet.RequestWrapper;import com.hoau.monitor.servlet.ResponseWrapper;import mons.logging.Log;import mons.logging.LogFactory;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.web.servlet.HandlerMapping;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Component@WebFilter(urlPatterns = {"/*"}, filterName = "monitorDataFilter")public class MonitorDataFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest);ResponseWrapper responseWrapper = new ResponseWrapper(httpServletResponse);filterChain.doFilter(requestWrapper, responseWrapper);byte[] bytes = responseWrapper.getBytes();val = new String(bytes, "UTF-8");//将数据 再写到 response 中byte[] gbks = val.getBytes("gbk");//这里编码转换操作servletResponse.setContentLength(gbks.length);servletResponse.getOutputStream().write(gbks);servletResponse.getOutputStream().flush();servletResponse.getOutputStream().close();}@Overridepublic void destroy() {}}

如果觉得《springboot 设置全局字符编码 解决乱码问题》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。