In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces how to solve the problem that the Chinese parameters of feign call are compiled by encode. It is very detailed and has a certain reference value. Interested friends must read it!
Why the Chinese parameters of Feign call are compiled by encode
The Post request is used when implementing a feign call, and the url parameters are concatenated. When the name value is in Chinese, it is translated by encode, and the data is not translated back by decode before the data is finally received. Explore the problem:
Feign:
@ FeignClient (name = "service-test") public interface TestServiceApi {@ PostMapping ("/ test/abc") public String getTestNo (@ RequestParam ("code") String code, @ RequestParam ("name") String name);}
Controller:
@ RequestMapping ("/ test") public interface TestController {@ Autowired private TestService testService; @ PostMapping ("/ abc") public String getTestNo (@ RequestParam ("code") String code, @ RequestParam ("name") String name) {return testService.query (code, name);}}
The Chinese parameters received in controller are translated by URIEncode.
The test was translated into:% E6%B5%8B%E8%AF%95
Find the way to assemble RequestTemplate in the entry class ReflectiveFeign of feign:
@ Override public RequestTemplate create (Object [] argv) {RequestTemplate mutable = new RequestTemplate (metadata.template ()); if (metadata.urlIndex ()! = null) {int urlIndex = metadata.urlIndex (); checkArgument (argv [urlIndex]! = null, "URI parameter% s was null", urlIndex); mutable.insert (0, String.valueOf (argv [urlIndex]));} Map varBuilder = new LinkedHashMap () For (Entry entry: metadata.indexToName (). EntrySet ()) {int I = entry.getKey (); Object value = argv [entry.getKey ()]; if (value! = null) {/ / Null values are skipped. If (indexToExpander.containsKey (I)) {value = expandElements (indexToExpander.get (I), value);} for (String name: entry.getValue ()) {varBuilder.put (name, value);} / / method for assembling template RequestTemplate template = resolve (argv, mutable, varBuilder) If (metadata.queryMapIndex ()! = null) {/ / add query map parameters after initial resolve so that they take / / precedence over any predefined values template = addQueryMapQueryParameters (argv, template);} if (metadata.headerMapIndex ()! = null) {template = addHeaderMapHeaders (argv, template);} return template;}
In the RequestTemplate class, if the param after url is concatenated, then it will be translated by encodeValueIfNotEncoded encode, but will not take the method of decode.
/ * Resolves any template parameters in the requests path, query, or headers against the supplied * unencoded arguments.
Relationship to JAXRS 2.0
This call is * similar to {@ code javax.ws.rs.client.WebTarget.resolveTemplates (templateValues, true)}, except * that the template values apply to any part of the request, not just the URL * / RequestTemplate resolve (Map unencoded, Map alreadyEncoded) {replaceQueryValues (unencoded, alreadyEncoded); Map encoded = new LinkedHashMap (); for (Entry entry: unencoded.entrySet ()) {final String key = entry.getKey (); final Object objectValue = entry.getValue () String encodedValue = encodeValueIfNotEncoded (key, objectValue, alreadyEncoded); encoded.put (key, encodedValue);} String resolvedUrl = expand (url.toString (), encoded). Replace ("+", "% 20"); if (decodeSlash) {resolvedUrl = resolvedUrl.replace ("% 2F", "/");} url = new StringBuilder (resolvedUrl); Map resolvedHeaders = new LinkedHashMap () For (String field: headers.keySet ()) {Collection resolvedValues = new ArrayList (); for (String value: valuesOrEmpty (headers, field)) {String resolved = expand (value, unencoded); resolvedValues.add (resolved);} resolvedHeaders.put (field, resolvedValues);} headers.clear (); headers.putAll (resolvedHeaders); if (bodyTemplate! = null) {body (urlDecode (expand (bodyTemplate, encoded) } return this;}
If the value passed in is in requestBody, it will not be translated by encode
@ Override public void encode (Object requestBody, Type bodyType, RequestTemplate request) throws EncodeException {/ / template.body (conversionService.convert (object, String.class)); if (requestBody! = null) {Class requestType = requestBody.getClass (); Collection contentTypes = request.headers () .get ("Content-Type"); MediaType requestContentType = null If (contentTypes! = null & &! contentTypes.isEmpty ()) {String type = contentTypes.iterator () .next (); requestContentType = MediaType.valueOf (type) } for (HttpMessageConverter messageConverter: this.messageConverters .getObject () .getConverters ()) {if (messageConverter.canWrite (requestType)) RequestContentType) {if (log.isDebugEnabled ()) {if (requestContentType! = null) {log.debug ("Writing [" + requestBody + "] as\"+ requestContentType +"\ "using [" + messageConverter + "]") } else {log.debug ("Writing [" + requestBody + "] using [" + messageConverter + "]");} FeignOutputMessage outputMessage = new FeignOutputMessage (request) Try {@ SuppressWarnings ("unchecked") HttpMessageConverter copy = (HttpMessageConverter) messageConverter; copy.write (requestBody, requestContentType, outputMessage);} catch (IOException ex) {throw new EncodeException ("Error converting request body", ex) } / / clear headers request.headers (null); / / converters can modify headers, so update the request / / with the modified headers request.headers (getHeaders (outputMessage.getHeaders () / / do not use charset for binary data if (messageConverter instanceof ByteArrayHttpMessageConverter) {request.body (outputMessage.getOutputStream (). ToByteArray (), null);} else {request.body (outputMessage.getOutputStream (). ToByteArray (), Charset.forName ("UTF-8")) } return;}} String message = "Could not write request: no suitable HttpMessageConverter" + "found for request type [" + requestType.getName () + "]"; if (requestContentType! = null) {message + = "and content type [" + requestContentType + "]" } throw new EncodeException (message);}}
To sum up the above debugging, if the parameters are stitched in Post, they will be translated by encode, and will not be translated by decode. If you use body to pass parameters, then there will be no translation problems. If you must use stitching to pass parameters, you can use the method.
1. @ RequestLine's annotation customizes the format of the parameters. For more information, please see how the annotation is used.
two。 The RequestInterceptor in Feign will pass the value decode to the extension method.
Record the feign multi-parameter problems encountered today in 1.Post mode
Examples of incorrect writing are as follows:
Public int save (@ RequestBody final User u, @ RequestBody final School s)
Cause of error:
There can be multiple @ RequestParam in a fegin, but there can be no more than one @ RequestBody,@RequestBody to modify an object, but there are both @ RequestBody and @ RequestParam
Then the parameters are placed in the Url of the request, and the @ RequestBody modifiers are placed in the submission object.
Attention! Used to process content encoded by @ RequestBody Content-Type for application/json,application/xml
Examples of correct writing are as follows:
Public int save (@ RequestBody final Person pgramming RequestParam ("userId") String userId,@RequestParam ("userTel") String userTel); 2.Get mode
Examples of incorrect writing are as follows:
@ RequestMapping (value= "/ test", method=RequestMethod.GET) Model test (final String name, final int age)
Cause of error:
Reason for exception: when using Feign, if you are sending a get request, you need to add @ RequestParam annotation to the request parameters. The Controller can be modified without this annotation, and @ RequestParam can be used to modify multiple parameters. @ RequestParam is used to modify parameters, not the entire object.
Note: @ RequestParam Content-Type is application/x-www-form-urlencoded and this is the default
Examples of correct writing are as follows:
@ GetMapping ("/ getSchoolDetail") public ResultMap getSchoolDetail (@ RequestParam ("kSchoolId") LongkSchoolId, @ RequestParam ("kSchoolYearId") Long kSchoolYearId). These are all the contents of this article entitled "how to solve the problem of feign calling Chinese parameters compiled by encode". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.