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 結尾

記錄知識點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM