• Java学习之Spring MVC路由映射


    Java学习之Spring MVC路由映射

    0x00 前言

    补充缺失的Javaweb部分内容。

    0x01 Spring MVC路由映射

    web.xml中配置解析路径

     <display-name>login</display-name>
     
    <servlet>  
        <servlet-name>loginservlet</servlet-name>  
        <jsp-file>/WEB-INF/view/login.jsp</jsp-file>
    </servlet>  
    <servlet-mapping>  
        <servlet-name>loginservlet</servlet-name>  
        <url-pattern>/login</url-pattern>  
    </servlet-mapping>  
    
    </web-app>
    
    

    访问http://xxx/login/login 即可访问到/WEB-INF/view/login.jsp文件

    Config类中配置

    WebMvcConfigurerAdapter类

    WebMvcConfigurerAdapter配置类是spring提供的一种配置方式,采用javabean的方式替代传统的基于xml的配置来对spring框架进行自定义的配置

     public void configurePathMatch(PathMatchConfigurer configurer) {}
        /*配置Web Service或REST API设计中内容协商,即根据客户端的支持内容格式情况来封装响应消息体,如xml,json*/
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
        /*配置路径匹配参数*/
        public void configureAsyncSupport(AsyncSupportConfigurer configurer) {}
        /* 使得springmvc在接口层支持异步*/
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}
        /* 注册参数转换和格式化器*/
        public void addFormatters(FormatterRegistry registry) {}
        /* 注册配置的拦截器*/
        public void addInterceptors(InterceptorRegistry registry) {}
        /* 自定义静态资源映射*/
        public void addResourceHandlers(ResourceHandlerRegistry registry) {}
        /* cors跨域访问*/
        public void addCorsMappings(CorsRegistry registry) {}
        /* 配置页面直接访问,不走接口*/
        public void addViewControllers(ViewControllerRegistry registry) {}
        /* 注册自定义的视图解析器*/
        public void configureViewResolvers(ViewResolverRegistry registry) {}
        /* 注册自定义控制器(controller)方法参数类型*/
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {}
        /* 注册自定义控制器(controller)方法返回类型*/
        public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {}
        /* 重载会覆盖掉spring mvc默认注册的多个HttpMessageConverter*/
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}
        /* 仅添加一个自定义的HttpMessageConverter,不覆盖默认注册的HttpMessageConverter*/
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}
        /* 注册异常处理*/
        public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
        /* 多个异常处理,可以重写次方法指定处理顺序等*/
        public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
    }
    
    
    package com.zeluli.springmvc;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    import org.springframework.web.servlet.view.JstlView;
    
    @Configuration
    @EnableWebMvc
    @ComponentScan("com.zeluli.springmvc")
    public class SpringMVCConfig  extends WebMvcConfigurerAdapter {
    	//路由映射的快捷设置
        //视图控制器配置
    	@Override
    	public void addViewControllers(ViewControllerRegistry registry) {
    		registry.addViewController("/indextest").setViewName("/index");
    	}
    	
    	@Bean
    	public InternalResourceViewResolver viewResolver(){
    		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    		viewResolver.setPrefix("/WEB-INF/classes/views/");
    		viewResolver.setSuffix(".jsp");
    		viewResolver.setViewClass(JstlView.class);
    		return viewResolver;
    	}	
    	
    	//创建自定义拦截器的对象
    	@Bean
    	public CustomInterceptor customInterceptor(){
    		return new CustomInterceptor();
    	}
    	
    	//添加自定义拦截器
    	@Override
    	public void addInterceptors(InterceptorRegistry registry) {
    		super.addInterceptors(registry);
    		registry.addInterceptor(customInterceptor());
    
    	}
    }
    
    
    package com.zeluli.springmvc;
    
    import javax.servlet.ServletRegistration.Dynamic;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    
    import org.springframework.web.WebApplicationInitializer;
    import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
    import org.springframework.web.servlet.DispatcherServlet;
    
    public class WebInitializer implements WebApplicationInitializer {
    
    	public void onStartup(ServletContext servletContext) throws ServletException {
    		
    		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    		context.register(SpringMVCConfig.class);
    		context.setServletContext(servletContext);
    		
    		Dynamic servlet = (Dynamic) servletContext.addServlet("dispatcher", new DispatcherServlet(context));
    		servlet.addMapping("/");
    		servlet.setLoadOnStartup(1);
    	}
    }
    
    

    相当于web.xml里面的

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    看到viewResolver方法中添加了/WEB-INF/classes/views/*.jsp的映射。

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class FirstController {
    	
    	@RequestMapping("/")
    	public String success() {
    		return "index";
    	}
    	
    }
    

    访问即可访问到/WEB-INF/classes/views/index.jsp

    http://localhost:8080/SpringMVCWithMaven_war/
    

    error 页面配置

    package com.zeluli.springmvc.advice;
    
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.context.request.WebRequest;
    import org.springframework.web.servlet.ModelAndView;
    
    @ControllerAdvice
    public class ExceptionHandlerAdvice {
    	@ExceptionHandler(value=Exception.class)	//拦截所有的Exception
    	public ModelAndView exception(Exception exception, WebRequest request) {
    		ModelAndView modelAndView = new ModelAndView("error");//error页面
    		modelAndView.addObject("errorMessage", exception.getMessage()); //错误信息
    		System.out.println(exception.getMessage());
    		return modelAndView;
    	}
    }
    
    
    package com.zeluli.springmvc.web;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class AdviceController {
    	@RequestMapping("/advice")
    	public String getMsg() {
    		throw new IllegalArgumentException("非常抱歉,参数有误");
    	}
    }
    

    多个路由映射同一方法

    可以将多个路由映射到同一个Controller的方法上。当我们给@RequestMapping的value属性赋值一个数组时,数组中的路径都会映射到该注解所修饰的方法中。

    	@RequestMapping(value = {"/name1", "/name2"}, produces = "text/plain;charset=UTF-8")
    	public @ResponseBody String remove(HttpServletRequest request) {
    		return  "请求地址:" + request.getRequestURI() + " 已经被访问了!";
    	}
    

    配置路由参数

    在路由配置中,我们可以为路由添加参数,然后使用@PathVariable注解来获取该路径变量的值。下方创建的sub2()方法的路由配置中就带有路径变量的,使用{路径变量}来声明路径变量,使用@PathVariable来获取路径变量。

    	@RequestMapping(value="/sub2/{value1}/{value2}/resource")
    	@ResponseBody
    	public String sub2(HttpServletRequest request, @PathVariable String value1, @PathVariable String value2) {
    		return "请求地址:" + request.getRequestURI() + " 移动端:" + value1 + " 平台:"+ value2;
    	}
    

    Get单请求

    	@RequestMapping(value = "/sub3")
    	@ResponseBody
    	public String sub3(HttpServletRequest request, String param) {
    		return  "请求地址" + request.getRequestURI() + " get参数 = " + param;
    	}
    

    Get多请求

    如果一个Get请求有多个参数怎么办呢?肯定不能再用上述方法类获取参数的值了。在Spring框架中,支持将获取的参数直接映射成Model。前提是参数的名称必须和特定Model中的属性名称相同,接下来我们就来做这件事情。将用户传入的参数直接映射成Model。

    首先我们得创建一个Model,下方这段代码就是我们创建的Model,该Model比较简单,只有两个属性,一个是studentNumber,另一个则是name。Model类中还对应着各个属性的getter和setter方法

    package com.zeluli.model;
    
    public class StudentModel {
        private String studentNumber;
        private String name;
        public StudentModel() {
            super();
        }
        public String getStudentNumber() {
            return studentNumber;
        }
        public void setStudentNumber(String studentNumber) {
            this.studentNumber = studentNumber;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    

    在路由对应的方法中直接使用相应的Model对象进行接收即可,在接收的过程中会将参数中相应的值赋给该Model对象中相应的属性。

    //将请求直接映射为Model
    //http://localhost:8080/SpringMVCWithMaven/route/sub4?studentNumber=12&name=zeluli
    @RequestMapping(value = "/sub4")
    @ResponseBody 
    public String sub4(HttpServletRequest request, StudentModel student) {
       return  "请求地址:" + request.getRequestURI() + " 参数studentNumber = " + student.getStudentNumber() + "   studentName:" + student.getName();
    }
    

    JSON数据输出

    //返回json数据
    	//http://localhost:8080/SpringMVCWithMaven/route/getjson?studentNumber=12&name=zeluli
    	@RequestMapping(value="/getjson", produces="application/json;charset=UTF-8")
    	@ResponseBody 
    	public StudentModel getJson(StudentModel student) {
    		return student;
    	}
    	
    

    返回XML数据

    @RequestMapping(value="/getxml", produces="application/xml;charset=UTF-8")
    @ResponseBody 
    public StudentModel getXML(StudentModel student) {
       return student;
    }
    

    接受JSON数据

    	public void getList(@RequestBody JSONObject json) {
    		//去除字符串
    		String uid = json.getString("uid");
    		System.out.println("uid:" + uid);
    

    路由快捷设置

    我们也可以在SpringMVC的配置文件中来快速的设置路由与JSP页面的映射关系,当然实现起来也是比较简单的。只需要我们的Spring的配置类继承于WebMvcConfigurerAdapter然后重写addViewControllers()方法即可。在addViewController()的方法中来进行路由到JSP页面的映射关系。

    	//路由映射的快捷设置
    	@Override
    	public void addViewControllers(ViewControllerRegistry registry) {
    		registry.addViewController("/indextest").setViewName("/index");
    	}
    

    参考文章

    https://www.cnblogs.com/ludashi/p/6432080.html

    0x02 结尾

    记录知识点

  • 相关阅读:
    leetcode — spiral-matrix-ii
    leetcode — spiral-matrix
    leetcode — maximum-subarray
    leetcode — n-queens
    leetcode — powx-n
    leetcode — anagrams
    bzoj 2194: 快速傅立叶之二 FFT
    bzoj 4503 两个串 快速傅里叶变换FFT
    Codeforces 762D Maximum path 动态规划
    Codeforces 762C Two strings 字符串
  • 原文地址:https://www.cnblogs.com/nice0e3/p/14777781.html
Copyright © 2020-2023  润新知