Source
The recent development of interface platform, the use of spring boot development, overall is quite smooth;
Interface platform will inevitably let others invoke the service, but also to call other external interfaces;
Suddenly one day, a service provider callback message appeared garbled, shaped like: ??????
, broke the quiet
Analysis process
Confirm to the service provider that the parameters passed by this interface use GBK encoding, WHT?? Now also useful GBK, not with UTF8 code?
Confirm my program code now:
server.tomcat.uri-encoding 未设置http.encoding.charset: UTF-8http.encoding.force-request: true
You can see that the configuration of the URI is undefined, and the search document explains that spring boot uses UTF8 encoding by default
The following two are the character sets that define HTTP and are used to set the character set of request and response;
Trace the source code, found that this character parameter will be used in Characterencodingfilter, the core method is to use: request.setCharacterEncoding("UTF-8")
, and is a global content
Resolution process
-
will get garbled with the UTF-8 encoding and then use GBK decoding, the following code, the result is: 锟 catty copy value of 锟 Jin copy
new String ( Source.getbytes ("UTF-8"), "GBK")
, through the data learned that GBK encoding->utf-8 decoding (garbled)->UTF-8 encoding (this step due to the particularity of UTF8 encoding, will add some header information)- >GBK decoding (resulting in irreversible results due to the addition of a special part)
-
called request.getcharacterencoding ("UTF-8")
in the method is not valid. This method of querying rquest shows that it is only valid to call this method before getting the parameter, but before that spring has done a lot of things for us, so it is invalid here;
-
Self-written filte to implement settings, but for unknown reasons or not valid
-
Inherits Characterencodingfilter
, and special processing is done for a specific URL, and the result is that the custom encoding takes effect, and the original UTF8 Encodingfilter is invalidated. Not even if you change your bean name.
-
Modify custom Encodingfilter to handle multiple character sets:
definition encodingfilter:
public class Muticharacterencodingfilter extends Characterencodingfilter implements ordered{//highest priority private int ord ER = integer.min_value; Private list<string> Mutiurls = new ArrayList (); Private String Muticharset = "GBK"; Public list<string> Getmutiurls () {return mutiurls; } public void Setmutiurls (list<string> mutiurls) {this.mutiurls = Mutiurls; } public String Getmuticharset () {return muticharset; } public void Setmuticharset (String muticharset) {this.muticharset = Muticharset; }/** * @param charset * @param muticharset * @param mutiurls * @param forcerequest * @param force Response */Public Muticharacterencodingfilter (String charset, String muticharset, list<string> Mutiurls, bo Olean Forcerequest, Boolean forceresponse) {super (charset,forcerequest,forceresponse); This.mutiurls = Mutiurls; This.muticharset = Muticharset; } publiC Muticharacterencodingfilter () {super (); } @Override protected void dofilterinternal (HttpServletRequest request, httpservletresponse response, Filterchain fi Lterchain) throws Servletexception, IOException {String path = Request.getrequesturi (); If this is the link, execute the Mutyencoding method if (Pathmatcherutil.matchany (Mutiurls,path)) {if (Muticharset! = null) { if (isforcerequestencoding () | | request.getcharacterencoding () = = null) {REQUEST.SETCHARACTE Rencoding (Muticharset); } if (Isforceresponseencoding ()) {response.setcharacterencoding (muticharset); }} filterchain.dofilter (Request,response); return; }//Otherwise use the default method Super.dofilterinternal (Request,response,filterchain); } @Override public int getorder () {return order; }
Set the appropriate content in the configuration:
http: encoding: charset: UTF-8 force-request: true force-response: false mutiCharset: GBK mutiUrls: - /notify/test
To generate an instance in config
//The first character set @Value (Value = "${spring.http.encoding.charset}") Private String charset; Whether to force apply to the request @Value (Value = "${spring.http.encoding.force-request}") Private Boolean forcerequest; Whether to force set to response @Value (Value = "${spring.http.encoding.force-response}") Private Boolean forceresponse; /** * Custom HTTP character set by default using the CharSet character set in a specific case using the second character set for the Eurocopter callback GBK encoding * only valid for form parameters in the post is invalid for parameters in URI only go to modify Tomcat character set encoding should not do so @return * * * @Bean () @ConfigurationProperties (prefix = "spring.http.encoding") @ConfigurationPropertie Sbinding public Muticharacterencodingfilter Muticharacterencodingfilter () {Muticharacterencodingfilter EncodingF Ilter = new Muticharacterencodingfilter (); Encodingfilter.setencoding (CharSet); Encodingfilter.setforcerequestencoding (forcerequest); Encodingfilter.setforceresponseencoding (Forceresponse); return encodingfilter; }
To solve this problem, can receive GKB encoded content;
But also has the flaw, only applies to the body content, does not apply to the link to the URL after the request parameter, if wants to support, can only modify tomcat-uri-encoding to UTF-8, hoped to be helpful to everybody.
Spring Boot Character Set encoding