Spring Boot开发之请求参数处理

Spring Boot开发之请求参数处理

1 请求参数处理

1 请求映射

Rest使用

  • @xxxMapping
  • Rest风格支持(使用HTTP请求方式动词来表示对资源的操作
    • 以前: /getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户
    • 现在: /user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户
    • 核心Filter;HiddenHttpMethodFilter
      • 用法: 表单method=post,隐藏域 _method=put
      • Spring Boot 中手动开启
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public String getUser(){
    
    
        return "GET-法外张三";
    }

    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public String saveUser(){
    
    
        return "POST-法外张三";
    }


    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    public String putUser(){
    
    
        return "PUT-法外张三";
    }

    @RequestMapping(value = "/user",method = RequestMethod.DELETE)
    public String deleteUser(){
    
    
        return "DELETE-法外张三";
    }


	@Bean
	@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
	@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
	public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
    
    
		return new OrderedHiddenHttpMethodFilter();
	}


//自定义filter
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
    
    
        HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
        methodFilter.setMethodParam("_m");
        return methodFilter;
    }

Rest原理

  • 表单提交会带上**_method=PUT**
  • 请求过来被HiddenHttpMethodFilter拦截
    • 请求是否正常,并且是POST
      • 获取到**_method**的值

      • 兼容以下请求;PUT.DELETE.PATCH

      • 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。-

        • 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的

测试工具

  • PostMan直接发送Put、delete等方式请求,无需Filter。

postwoman,apipost等客户端工具都可以.

配置开启表单设置

spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true   #开启页面表单的Rest功能

2 请求映射原理

从HttpServlet的doGet方法,到FrameworkServlet的processRequest到doService方法,到DispatcherServlet的doService具体实现.

SpringMVC功能分析:

org.springframework.web.servlet.DispatcherServlet->doDispatch()

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
    
    
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
    
    
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// 找到当前请求使用哪个Handler(Controller的方法)处理
				mappedHandler = getHandler(processedRequest);
                
                // HandlerMapping:处理器映射。/xxx->>xxxx

RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。

所有的请求映射都在HandlerMapping中:

  • SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;

  • SpringBoot自动配置了默认 的 RequestMappingHandlerMapping 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息

    • 如果有就找到这个请求对应的handler

      • 如果没有就是下一个 HandlerMapping
    • 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。

  • 自定义 HandlerMapping:

	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    
    
		if (this.handlerMappings != null) {
    
    
			for (HandlerMapping mapping : this.handlerMappings) {
    
    
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
    
    
					return handler;
				}
			}
		}
		return null;
	}

猜你喜欢

转载自blog.csdn.net/ABestRookie/article/details/127397288