In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article shows you how to parse the parameters of the SpringMVC method in the Controller layer, the content is concise and easy to understand, it will definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.
Use version:
Spring-boot: 2.1.6.RELEASE
Sping: 5.1.8.RELEASE
Java: openjdk 11.0.13
Custom parameter parser
To be able to implement a custom parameter parser, you just need to implement HandlerMethodArgumentResolver and add it to WebMvcConfigurer#addArgumentResolvers.
Realize the effect
Let's add a client-type parameter to get the request header as an example. Define the annotation @ ClientTypeMark and enum ClientType to inject values into header.
@ Target ({ElementType.PARAMETER}) @ Retention (RetentionPolicy.RUNTIME) @ Documentedpublic @ interface ClientTypeMark {} public enum ClientType {WEB, MOBILE, UNKNOWN;}
The final effect of the implementation is that in the method of Controller, you can use it as follows.
@ RestController@RequestMapping ("/ client") public class ClientTypeEndpoint {@ GetMapping ("/ cur") public ClientType getCurClientType (@ ClientTypeMark ClientType clientType) {return clientType;}} implementation and configuration
Implement HandlerMethodArgumentResolver as follows, which is used to parse client-type in header and convert it to ClientType.
Package io.github.donespeak.springbootsamples.web.common;import org.apache.commons.lang3.StringUtils;import org.springframework.core.MethodParameter;import org.springframework.web.bind.support.WebDataBinderFactory;import org.springframework.web.context.request.NativeWebRequest;import org.springframework.web.method.support.HandlerMethodArgumentResolver;import org.springframework.web.method.support.ModelAndViewContainer;public class CurClientTypeMethodArgumentResolver implements HandlerMethodArgumentResolver {private final String [] CLIENT_TYPE_HEADER_NAMES = {"client-type", "CLIENT-TYPE", "Client-Type"} / / Select the parameter to be injected: determine whether the parameter meets the parsing condition @ Override public boolean supportsParameter (MethodParameter param) {return param.hasParameterAnnotation (ClientTypeMark.class) & & ClientType.class.isAssignableFrom (param.getParameterType ()) } / / the return value will be injected into the selected parameter @ Override public Object resolveArgument (MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {String clientType = null; for (String clientTypeHeader: CLIENT_TYPE_HEADER_NAMES) {clientType = nativeWebRequest.getHeader (clientTypeHeader); if (StringUtils.isNotBlank (clientType)) {break }} try {return StringUtils.isBlank (clientType)? ClientType.UNKNOWN: ClientType.valueOf (clientType.toUpperCase ());} catch (Exception e) {return ClientType.UNKNOWN;}}
For the configuration to take effect, you can add a parser as follows.
@ Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@ Override public void addArgumentResolvers (List argumentResolvers) {/ / parse @ CurUserId annotation parameter argumentResolvers.add (new CurClientTypeMethodArgumentResolver ());}}
At this point, the work of customizing the parameter parser is complete.
Spring provides parsers
When you complete the custom parser above, you will have a general idea of how Spring parses other parameters in the Controller layer.
Here are some of the default parameter resolvers for Spring Mvc.
Package org.springframework.web.servlet.mvc.method.annotation;public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean {... / * Return the list of argument resolvers to use including built-in resolvers * and custom resolvers provided via {@ link # setCustomArgumentResolvers}. * / private List getDefaultArgumentResolvers () {List resolvers = new ArrayList (); / / Annotation-based argument resolution / / Resolution: @ RequestParam (required = false) resolvers.add (new RequestParamMethodArgumentResolver (getBeanFactory (), false)); / / Resolution: @ RequestParamMap resolvers.add (new RequestParamMapMethodArgumentResolver ()); / / Resolution: @ PathVariable resolvers.add (new PathVariableMethodArgumentResolver ()) / / parse: @ PathVariableMap resolvers.add (new PathVariableMapMethodArgumentResolver ()); / / parse: @ MatrixVariable resolvers.add (new MatrixVariableMethodArgumentResolver ()); / / parse: @ MatrixVariableMap resolvers.add (new MatrixVariableMapMethodArgumentResolver ()); / / resolve: @ ModelAttribute (required = false) resolvers.add (new ServletModelAttributeMethodProcessor (false)) / / parse: @ RequestBody resolvers.add (new RequestResponseBodyMethodProcessor (getMessageConverters (), this.requestResponseBodyAdvice)); / / parse: @ RequestPart resolvers.add (new RequestPartMethodArgumentResolver (getMessageConverters (), this.requestResponseBodyAdvice)); / / parse: @ RequestHeader resolvers.add (new RequestHeaderMethodArgumentResolver (getBeanFactory (); / / resolve: @ RequestHeaderMap resolvers.add (new RequestHeaderMapMethodArgumentResolver ()) / / parse: @ CookieValue resolvers.add (new ServletCookieValueMethodArgumentResolver (getBeanFactory (); / / parse: @ Value resolvers.add (new ExpressionValueMethodArgumentResolver (getBeanFactory (); / / parse: @ SessionAttribute resolvers.add (new SessionAttributeMethodArgumentResolver ()); / / resolve: @ RequestAttribute resolvers.add (new RequestAttributeMethodArgumentResolver ()) / / Type-based argument resolution / / parsing: WebRequest, ServletRequest, MultipartRequest, HttpSession, / / Principal, Locale, TimeZone, java.time.ZoneId, InputStream / / java.io.Reader, org.springframework.http.HttpMethod resolvers.add (new ServletRequestMethodArgumentResolver ()); / / parsing: ServletResponse, OutputStream, Writer resolvers.add (new ServletResponseMethodArgumentResolver ()) / / parse: @ HttpEntity, @ RequestEntity resolvers.add (new HttpEntityMethodProcessor (getMessageConverters (), this.requestResponseBodyAdvice)); / / parse: RedirectAttributes resolvers.add (new RedirectAttributesMethodArgumentResolver ()); / / parse: org.springframework.ui.Model, the value is ModelAndViewContainer#getModel resolvers.add (new ModelMethodProcessor ()); / / parse: Map, the value is ModelAndViewContainer#getModel resolvers.add (new MapMethodProcessor ()) / / parse: org.springframework.validation.Errors resolvers.add (new ErrorsMethodArgumentResolver ()); / / parse: org.springframework.web.bind.support.SessionStatus resolvers.add (new SessionStatusMethodArgumentResolver ()); / / parse: UriComponentsBuilder or ServletUriComponentsBuilder resolvers.add (new UriComponentsBuilderMethodArgumentResolver ()); / / Custom arguments if (getCustomArgumentResolvers ()! = null) {resolvers.addAll (getCustomArgumentResolvers ()) } / / Catch-all / / parse: @ RequestParam (required = true) resolvers.add (new RequestParamMethodArgumentResolver (getBeanFactory (), true)); / / parse: @ ModelAttribute (required = true) resolvers.add (new ServletModelAttributeMethodProcessor (true)); return resolvers;}.} some use Tricky
Adjust the order of the parser
In a development that uses spring security, the defined UserDetials implementation class not only implements UserDetails but also implements an Account interface. When using it, you want to achieve the following results.
Public void doSomething (@ AuthenticationPrincipal Account accout) {}
However, because it is used at the same time, the ProxyingHandlerMethodArgumentResolver provided by spring-data,spring-data injects Account before the AuthenticationPrincipalArgumentResolver. ProxyingHandlerMethodArgumentResolver intercepts all interfaces that are not defined in org.springframework and attempts to assign values. In order to assign a value to Account properly, you need to adjust the position of both. The implementation is as follows:
Import java.util.LinkedList;import java.util.List;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver;import org.springframework.stereotype.Component;import org.springframework.web.method.support.HandlerMethodArgumentResolver;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter / * move AuthenticationPrincipalArgumentResolver to the front. If no adjustment is made, * because ProxyingHandlerMethodArgumentResolver is in front of AuthenticationPrincipalArgumentResolver, * @ AuthenticationPrincipal Account account cannot be injected * / public class ArgumentResolverBeanPostProcessor implements BeanPostProcessor {private static final String BEAN_REQUEST_MAPPING_HANDLER_ADAPTER = "requestMappingHandlerAdapter"; @ Override public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException {if (beanName.equals (BEAN_REQUEST_MAPPING_HANDLER_ADAPTER)) {RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean List argumentResolvers = adapter.getArgumentResolvers (); LinkedList resolversAdjusted = new LinkedList (argumentResolvers); argumentResolvers.stream () .forEach (r-> {if (AuthenticationPrincipalArgumentResolver.class.isInstance (r)) {resolversAdjusted.addFirst (r);} else {resolversAdjusted.add (r);}}) Adapter.setArgumentResolvers (resolversAdjusted);} return bean;}} the above content is how to parse the parameters of the SpringMVC method in the Controller layer. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are 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.