• MVC框架,SpringMVC



    MVC框架会处理类似如下相同的技术需求:

    • HTTP URL映射到Controller某个方法。
    • HTTP参数映射到Controller方法的参数上,比如参数映射到某个Java对象,或者上传附件映射到某个File对象上;
    • 参数的校验;
    • MVC错误处理;
    • MVC如何调用视图;
    • MVC中如何序列化对象成JSON;拦截器等高级定制。

    使用Controller

    MVC框架有时候返回的是JSON字符串,如果想直接返回内容而不是视图名,则需要在方法上使用@ResponseBody

    @RequestMapping("/index.json")
    public @ResponseBody String say(){
    	return "hello world";
    }
    

    RequestBody注解直接将返回的对象输出到客户端,如果是字符串,则直接返回,如果不是,则默认使用Jackson序列号成JSON字符串后输出。

    URL映射到方法

    @RequestMapping

    可使用@RequestMapping来映射URL,比如/test到某个Controller类,或者是某个具体的方法。通常类上的注解@RequestMapping用来标注请求的路径,方法上的@RequestMapping注解进一步映射特定URL到具体的处理方法。

    RequestMapping有多个属性来进一步匹配HTTP请求到Controller方法。分别是:

    • value:请求的URL的路径,支持URL模板、正则表达式。
    • method:HTTP请求方法,有GET、POST、PUT等。
    • consumes:允许的媒体类型,如consumes=“application/json”,对应于请求的HTTP的Content-Type。
    • produces:响应的媒体类型,如produces=“application/json”,对应于HTTP的Accept字段。
    • params:请求的参数,如params=“action=update”。
    • headers:请求的HTTP头的值,如hearder=“myHeader=myValue”。

    URL路径匹配

    属性value用于匹配一个URL映射,value支持简单的表达式来匹配:

    @RequestMapping(value="/get/{id}.json")
    public @RequestBody User getById( @PathVariable("id") Long id ){
    	return userService.getUserById(id);
    }
    //注解@PathVariable作用在方法参数上,表示该参数的值来自于URL路径。
    

    Ant路径表达式

    Ant用符号"*"来表示匹配任意字符,用**来表示统配任意路径,用?来匹配单个字符。

    如果一个请求有多个@RequestMapping能够匹配,通常是更具体的匹配会作为处理此请求的方法。

    • 有通配符的低于每一通配符的,比如.user/add.json比/user/*.json优先匹配;
    • 有**通配符的低于有*通配符的。

    URL映射也可以使用${}来获得系统的配置或者环境变量,通常用于Controller路径是通过配置文件设定的情况。

    @RequestMapping(/${query.all}.json)
    @RequestBody
    public List<User> all(){
    	return userService.allUser();
    }
    

    HTTP method匹配

    @RequestMapping提供method属性来映射对应HTTP的请求方法,通常HTTP请求方法有如下内容:

    • GET,用来获取URL对应的内容。
    • POST,用来向服务器提交信息。
    • HEAD,同GET,但不返回消息体,通常用于返回URL对应的元信息,如过期时间等。搜索引擎通常用HEAD来获取网页信息。
    • PUT,同POST,用来向服务器提交信息,但语义上更像一个更像操作,同一个数据,多次PUT,也不会导致数据发生改变。
    • DELETE,删除对应的资源信息。
    • PATCH,类似PUT,表示信息的局部更像。

    Spring提供了简化后@RequestingMapping,提供了新的注解来表示HTTP方法:

    • GetMapping
    • PostMapping
    • PutMapping
    • DeleteMapping
    • PatchMapping

    consumes和produces

    属性consumes意味着请求的HTTP头的Content-Type媒体类型与consumes的值匹配,才能调用此方法。

    @GetMapping(value="/consumes/test.json",consumes = "application/json" )
    @ResponseBody
    public User forJson(){
    	return userService.queryById(11);
    }
    

    这里映射指定请求的媒体类型是application/json,此方法接受一个AJAX请求,如果通过浏览器直接访问,则报错,因为通过浏览器访问,通常并没有设置Content-Type,所以说null不支持。

    为了成功调用上述Controller方法,AJAX调用必须设置Content-Type为application/json,如下代码:

    $.ajax({
    	type: "get",
    	url: "/consumes/test.jgon",
    	contentType: "application/json",
    	.....
    });
    

    produces 属性对应于HTTP请求的Accept字段,只有匹配上的方法才能被调用。

    @GetMapping(path = "/user/{userId}"), produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public User getUser(@Pathvariable Long userId,Model model){
    	return userService.getUserById(userId);
    }
    

    通常浏览器都会将Accept设置为*.*,因此通过浏览器直接访问"/user/1",浏览器总是返回id为1的用户信息,并转成JSON格式。

    params和header匹配

    可从请求参数或者HTTP头中提取值来进一步确定调用的方法,有三种形式:

    • 如果存在参数,则通过
    • 如果不存在参数,则通过
    • 如果参数等于某一个具体值,则通过。。
    @PostMapping( path = "/updata.json", params = "action=save")
    @ResponseBody
    public void saveUser(){
    	...
    }
    
    @PostMapping( path = "/updata.json", params = "action=update")
    @ResponseBody
    public void saveUser(){
    	...
    }
    

    header与params一样。

    @PostMapping( path = "/updata.json", params = "action=save")
    @ResponseBody
    public void saveUser(){
    	...
    }
    

    方法参数

    Spring的Controller方法可以接受多种类型参数,如path,还有MVC的Model。此外,还有:

    • @PathVariable,将URL中的值映射到方法参数中。
    • Model,Spring中通用的MVC模型,可使用Map和ModelMap作为渲染视图的模型。
    • ModelAndView:包含了模型和视图路径的对象。
    • JavaBean:将HTTP参数映射到JavaBean对象。
    • MultipartFile:用于处理文件上传。
    • @ModelAttribute:使用该注解的变量将作为Model的一个属性。
    • @RequestParam:对应于HTTP请求的参数,自动转化为参数对应的类型。
    • @RequestHeader:对应于HTTP请求头参数,自动转化为对应的类型。
    • @RequestBody:自动将请求内容转为指定的对象。
    • @SessionAttribute:该方法标注的变量来自于Session的属性。
    • @InitBinder,用在方法上,说明这个方法会注册多个转化器,用来个性化地将HTTP请求参数转化成对应的Java对象,如转化为日期类型,浮点类型,JavaBean等。

    WebMvcConfigurer

    WebMvcConfigurer用来全局定制化Spring Boot的MVC特性。

    @Configuration
    public class MvcConfigurer implements WebMvcConfigurer {
    	//拦截器
    	public void addInterceptors(InterceptorRegistory registry){
    
    	}
    
    	//跨域访问设置
    	public void addCorsMappings(CorsRegistry registry){
    
    	}
    
    	//格式化
    	public void addFormatters(FormatterRegistry registry){
    
    	}
    
    	//URI到视图的映射
    	public void addViewControllers(ViewControllerRegistry registry){
    
    	}
    }
    

    拦截器

    通过addInterceptors方法可以设置多个拦截器,比如对特定的URI设定拦截器以检查用户是否登录,打印处理用户请求耗费的时间等。

    public void addInterceptors(InterceptorRegistry registry){
    	//增加一个拦截器,检查会话,URI以admin开头的都是要此拦截器
    	registry.addInterceptor(new SesssionHandlerInterceptor()).addPathPatterns("/admin/**");
    }
    
    class SessionHandlerInterceptor implements HandlerInterceptor{
    	class boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler)
    		throws Exception{
    			User user = (User) request.getSeesion().getAttribute("user");
    			if(user == null){
    				//如果没有登录,重定向到login.html
    				response.sendRedirect("/login.html");
    				return false;;
    			}
    			return true;
    	}
    
    	public void postHandle(
    		HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView)
    		throws Exception{
    		//Controller方法处理完毕后,调用此方法
    	}
    
    	@Override
    	public void afterCompletion(
    		HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex)
    		throws Exception{
    			//页面渲染完成后调用此方法,通常用来清除某些资源。
    		}
    	
    }
    

    跨域访问

    Spring Boot提供了对CORS的支持,可以实现addCorsMappings接口来添加特定的配置:

    @Override
    public void addCorsMappings(CoresRegistry registry){
    	registry.addMapping("/**");
    }
    

    允许所有跨域访问,或者更为精细,如:

    public void addCorsMappings(CorsRegistry registry){
    	registry.addMapping("/api/**")
    		.allowwedOrigins("http://domain2.com")
    		.addwebMethods("POST","GET");
    }
    

    注册Controller

    应用有时候没有必要为一个URL指定一个Controller方法,可以直接将URI请求转到对模板的渲染上,

    @RequestMapping("/"){
    	public String index(){
    		return "/index.btl";
    	}
    }
    

    可以直接通过ViewControllerRegistry注册一个:

    public void addViewControllers(ViewControllerRegistry registry) {
    	registry.addViewController("/index.html").setViewName("/index.btl");;
    	registry.addRedirectViewController("/**/*.do","index.html");
    }
    

    对于index.html的请求,设置返回的视图为index.btl。
    所有以.do结尾的请求重定向到/index.html请求。

  • 相关阅读:
    android 网络请求Volley的简单使用
    数据加密,android客户端和服务器端可共用
    非常有用的GitHub链接
    android开发——Android开发中的47个小知识
    EditText禁用系统键盘,光标可以继续使用
    Android Studio 快速开发
    Android系统拍照之后回显并且获取文件路径
    Android为TV端助力 doc里面adb连接出现问题的解决方法
    Android为TV端助力 自定义view中findViewById为空的解决办法
    Android为TV端助力 VelocityTracker 速度追踪器的使用及创建
  • 原文地址:https://www.cnblogs.com/aixing/p/13327481.html
Copyright © 2020-2023  润新知