springboot2学习笔记(三)

参数处理原理

HandlerMapping中找到能处理请求的Handler(Controller.method())
为当前Handler 找一个适配器 HandlerAdapter; RequestMappingHandlerAdapter
适配器执行目标方法并确定方法参数的每一个值

  1. HandlerAdapter
    0-支持方法标注@RequestMapping
    1-支持函数编程
    在这里插入图片描述
  2. 执行目标方法
// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// No synchronization on session demanded at all...
//执行目标方法
			mav = invokeHandlerMethod(request, response, handlerMethod);


Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);//真正执行目标方法

//获取每一个参数的值
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);

  1. 参数解析器
    确定将要执行的目标方法的每一个参数值是什么
    SpringMvc目标方法能写多少种参数类型,取决于参数解析器
    在这里插入图片描述
    在这里插入图片描述
    当前解析器支持解析哪种参数
    如果支持调用resolveArgument
  2. 返回值处理器

在这里插入图片描述

  1. 如何确定目标方法每一个参数的值
============InvocableHandlerMethod==========================
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {

		MethodParameter[] parameters = getMethodParameters();
		if (ObjectUtils.isEmpty(parameters)) {
			return EMPTY_ARGS;
		}

		Object[] args = new Object[parameters.length];
		for (int i = 0; i < parameters.length; i++) {
			MethodParameter parameter = parameters[i];
			parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
			args[i] = findProvidedArgument(parameter, providedArgs);
			if (args[i] != null) {
				continue;
			}
			if (!this.resolvers.supportsParameter(parameter)) { //判断是否支持
				throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
			}
			try {
				args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);//解析这个参数
			}
			catch (Exception ex) {
				// Leave stack trace for later, exception may actually be resolved and handled...
				if (logger.isDebugEnabled()) {
					String exMsg = ex.getMessage();
					if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
						logger.debug(formatArgumentError(parameter, exMsg));
					}
				}
				throw ex;
			}
		}
		return args;
	}

挨个判断所有参数解析器那个支持解析这个参数

解析这个参数的值

复杂参数

Map<String,Object> map, Model model, HttpServletRequest request 都是可以给request域中放数据,
request.getAttribute();来获取

@GetMapping("/params")
    public String testParam(Map<String,Object> map,
                            Model model,
                            HttpServletRequest request,
                            HttpServletResponse response) {
        map.put("hello","6666");
        model.addAttribute("world","7777");
        request.setAttribute("message","helloWorld");

        Cookie cookie = new Cookie("c1","v1");
        response.addCookie(cookie);
        return "forward:/success";
    }
@ResponseBody
    @GetMapping("/success")
    public Map success(@RequestAttribute(value = "msg",required = false) String msg,
                       @RequestAttribute(value = "code",required = false) String code,
                       HttpServletRequest request) {
        Object hello = request.getAttribute("hello");
        Object world = request.getAttribute("world");
        Object message = request.getAttribute("message");


        Object msg1 = request.getAttribute("msg");
        Map<String,Object> map = new HashMap<>();
        map.put("reqMethod_msg",msg1);
        map.put("annotation_msg",msg);
        map.put("hello",hello);
        map.put("world",world);
        map.put("message",message);
        return map;
    }

@Configuration(proxyBeanMethods = false)
public class WebConfig /*implements WebMvcConfigurer */ {
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
        HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
        methodFilter.setMethodParam("_m");
        return methodFilter;
    }

//    @Override
//    public void configurePathMatch(PathMatchConfigurer configurer) {
//        UrlPathHelper urlPathHelper = new UrlPathHelper();
//        //不移除分号
//        urlPathHelper.setRemoveSemicolonContent(false);
//        configurer.setUrlPathHelper(urlPathHelper);
//    }

    @Bean //WebMvcConfigurer
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void configurePathMatch(PathMatchConfigurer configurer) {
                UrlPathHelper urlPathHelper = new UrlPathHelper();
                urlPathHelper.setRemoveSemicolonContent(false);
                configurer.setUrlPathHelper(urlPathHelper);
            }


//自定义参数类型----改用lambda表达式写法
            @Override
            public void addFormatters(FormatterRegistry registry) {
                registry.addConverter(new Converter<String, Pet>() {
                    @Override
                    public Pet convert(String source) {
                        //fsf,sf
                        if (!StringUtils.isEmpty(source)) {
                            Pet pet = new Pet();
                            String[] split = source.split(",");
                            pet.setName(split[0]);
                            pet.setAge(Integer.valueOf(split[1]));
                            return pet;
                        }
                        return null;
                    }
                });
            }

//            @Override
//            public void addFormatters(FormatterRegistry registry) {
//                registry.addConverter((String source) -> {
//                    if (!StringUtils.isEmpty(source)) {
//                        Pet pet = new Pet();
//                        String[] split = source.split(",");
//                        pet.setName(split[0]);
//                        pet.setAge(Integer.valueOf(split[1]));
//                        return pet;
//                    }
//                    return null;
//
//                });
//            }
        };
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值