SpringMVC——@RequestMapping詳解

SpringMVC——@RequestMapping詳解——20200129

初學整理

                                                                                                                                      springmvc容器是spring容器的子容器

DemoController.java

package com.bjsxt.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bjsxt.pojo.Demo;
import com.bjsxt.pojo.Demo2;
import com.bjsxt.pojo.People;

@Controller
public class DemoController {

//注意傳參需要的註解及其屬性
/**	目錄:
	
1.@RequestMapping 用法詳解之地址映射-----------------------------------------45
	(6個屬性value,method,consumes,produces,params,headers);
2.@RequestParam @RequestBody @PathVariable 等參數綁定註解詳解(轉)------------174
	@PathVariable,
	@RequestHeader,@CookieValue,
	@RequestParam,@RequestBody,
	@SessionAttributes,@ModelAttribute
3.@RequestMapping 使用須知---具體的功能方面----------------------------------325
	@RequestMapping 一共有五種映射方式:@RequestMapping("")或@RequestMapping(value={"",""})
		1、標準URL 映射:
		2、Ant 風格的 URL 映射(通配符):?-->匹配任何單字符;*-->匹配任意數量的字符(含0個);**-->匹配任意數量的目錄(含0個)
		3、佔位符URL 映射(restful傳值方式):@RequestMapping("/user/{userId}/show")
		4、限制請求方法的URL 映射:method=RequestMethod.POST
		5、限制請求參數的URL 映射:params="userId"
	要注意@PathVariable("") 和 @RequestParam("") 的不同:
				@PathVariable("") 是將 URL 中佔位符處的值綁定到方法參數上
				@RequestParam("") 是將 URL 後的請求參數綁定到方法參數上	
 */
/*
@RequestMapping 用法詳解之地址映射(轉)
一、引言:
	前段時間項目中用到了RESTful模式來開發程序,但是當用POST、PUT模式提交數據時,
	發現服務器端接受不到提交的數據(服務器端參數綁定沒有加任何註解),
	查看了提交方式爲application/json, 而且服務器端通過request.getReader()打出的數據裏
	確實存在瀏覽器提交的數據。爲了找出原因,便對參數綁定
	(@RequestParam、 @RequestBody、 @RequestHeader 、 @PathVariable)進行了研究,
	同時也看了一下HttpMessageConverter的相關內容,在此一併總結。
 
二、簡介:
@RequestMapping()
RequestMapping是一個用來--處理請求地址映射 的註解,可用於--類或方法 上。
	用於類上,表示類中的--所有響應請求的方法都是以--該地址 作爲--父路徑。
RequestMapping註解有六個屬性,下面我們把她分成三類進行說明。
	1、 value,method;
		value:	指定請求的實際地址,指定的地址可以是URI Template 模式(後面將會說明);
		method:	指定請求的method類型, GET、POST、PUT、DELETE等;

	2、 consumes,produces;
		consumes:指定處理請求的提交內容類型(Content-Type),例如application/json,text/html;
		produces:指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回;
					表示響應頭中 Content-Type 取值

	3、 params,headers;
		params: 指定request中必須包含某些參數值是,才讓該方法處理。
		headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。

三、示例:
1、value  / method 示例
	默認RequestMapping("....str...")即爲value的值;

	@Controller
	@RequestMapping("/appointments")
	public class AppointmentsController {
	    private AppointmentBook appointmentBook;
	    @Autowired
	    public AppointmentsController(AppointmentBook appointmentBook) {
	        this.appointmentBook = appointmentBook;
	    }
	    @RequestMapping(method = RequestMethod.GET)
	    public Map<String, Appointment> get() {
	        return appointmentBook.getAppointmentsForToday();
	    }
	    @RequestMapping(value="/{day}", method = RequestMethod.GET)
	    public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
	        return appointmentBook.getAppointmentsForDay(day);
	    }
	    @RequestMapping(value="/new", method = RequestMethod.GET)
	    public AppointmentForm getNewForm() {
	        return new AppointmentForm();
	    }
	    @RequestMapping(method = RequestMethod.POST)
	    public String add(@Valid AppointmentForm appointment, BindingResult result) {
	        if (result.hasErrors()) {
	            return "appointments/new";
	        }
	        appointmentBook.addAppointment(appointment);
	        return "redirect:/appointments";
	    }
	}
	value的uri值爲以下三類:
	
	A) 可以指定爲普通的具體值;
	B) 可以指定爲含有某變量的一類值(URI Template Patterns with Path Variables);
	C) 可以指定爲含正則表達式的一類值( URI Template Patterns with Regular Expressions);
	
	example B):
	@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
	public String findOwner(@PathVariable String ownerId, Model model) {
	  Owner owner = ownerService.findOwner(ownerId);  
	  model.addAttribute("owner", owner);  
	  return "displayOwner"; 
	}
	example C):
	@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
	  public void handle(@PathVariable String version, @PathVariable String extension) {    
	    // ...
	  }
	}

2、consumes / produces 示例
	cousumes的樣例:
		@Controller
		@RequestMapping(value="/pets",method=RequestMethod.POST,consumes="application/json")
		public void addPet(@RequestBody Pet pet, Model model) {    
		    // implementation omitted
		}
		方法僅處理request Content-Type爲“application/json”類型的請求。

	produces的樣例:
		@Controller
		@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
		@ResponseBody
		public Pet getPet(@PathVariable String petId, Model model) {    
		    // implementation omitted
		}
		方法僅處理request請求中Accept頭中包含了"application/json"的請求,同時暗示了返回的內容類型爲application/json;

3 params、headers 示例
	params的樣例:
		@Controller
		@RequestMapping("/owners/{ownerId}")
		public class RelativePathUriTemplateController {
		  @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
		  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
		    // implementation omitted
		  }
		}
		僅處理請求中包含了名爲“myParam”,值爲“myValue”的請求;

	headers的樣例:
		@Controller
		@RequestMapping("/owners/{ownerId}")
		public class RelativePathUriTemplateController {
			@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=http://www.ifeng.com/")
			  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
			    // implementation omitted
			}
		}
		僅處理request的header中包含了指定“Refer”請求頭和對應值爲“http://www.ifeng.com/”的請求;

上面僅僅介紹了,RequestMapping指定的方法處理哪些請求,下面一篇將講解怎樣處理request提交的數據(數據綁定)和返回的數據。
 
------------------------
參考資料:
1、 Spring Web Doc: 
spring-3.1.0/docs/spring-framework-reference/html/mvc.html
轉載於: https://www.cnblogs.com/qq78292959/p/3760560.html
===============================================================================================================================================
@RequestParam @RequestBody @PathVariable 等參數綁定註解詳解(轉)
一、引言:
接上一篇文章,對@RequestMapping進行地址映射講解之後,該篇主要講解request 數據到handler method 參數數據的綁定所用到的註解和什麼情形下使用;

二、簡介:
	handler method 參數綁定常用的註解,我們根據他們處理的Request的不同內容部分分爲四類:(主要講解常用類型)
	A、處理request uri 部分(這裏指uri template中variable,不含queryString部分)的註解:   @PathVariable;(使用restful模式)
	B、處理request header部分的註解:   @RequestHeader, @CookieValue;
	C、處理request body部分的註解:@RequestParam,  @RequestBody;		請求參數
	D、處理attribute類型是註解: @SessionAttributes, @ModelAttribute;

1、 @PathVariable 	接收請求路徑中佔位符的值(restful模式)
	當使用@RequestMapping URI template 樣式映射時, 即 someUrl/{paramId}, 這時的paramId可通過 @Pathvariable註解綁定它傳過來的值到方法的參數上。

	示例代碼:(使用restful模式)
	@Controller
	@RequestMapping("/owners/{ownerId}")
	public class RelativePathUriTemplateController {
	  @RequestMapping("/pets/{petId}")
	  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
	    // implementation omitted
	  }
	}
	上面代碼把URI template 中變量 ownerId的值和petId的值,綁定到方法的參數上。
	若方法參數名稱和需要綁定的uri template中變量名稱不一致,需要在@PathVariable("name")指定uri template中的名稱。

2、 @RequestHeader、@CookieValue
	2.1@RequestHeader 註解,可以把Request請求header部分的值綁定到方法的參數上。
	示例代碼:
	這是一個Request 的header部分:
		Host                    localhost:8080
		Accept                  text/html,application/xhtml+xml,application/xml;q=0.9
		Accept-Language         fr,en-gb;q=0.7,en;q=0.3
		Accept-Encoding         gzip,deflate
		Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7
		Keep-Alive              300
	control部分
		@RequestMapping("/displayHeaderInfo.do")
		public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,
		                              @RequestHeader("Keep-Alive") 		long keepAlive)  {
		  //...
		}
	上面的代碼,把request header部分的 Accept-Encoding的值,綁定到參數encoding上了, Keep-Alive header的值綁定到參數keepAlive上。

	2.2@CookieValue 註解,可以把Request header中關於cookie的值綁定到方法的參數上。
	例如有如下Cookie值:
		JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
	參數綁定的代碼:
		@RequestMapping("/displayHeaderInfo.do")
		public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie)  {
		  //...
		}
		即把JSESSIONID的值綁定到參數cookie上。

3、@RequestParam, @RequestBody
	3.1@RequestParam 
		A) 常用來處理簡單類型的綁定,通過Request.getParameter() 獲取的String可直接轉換爲簡單類型的情況
			(String--> 簡單類型的轉換操作由ConversionService配置的轉換器來完成);因爲使用request.getParameter()方式獲取參數,
			所以可以處理get 方式中queryString的值,也可以處理post方式中 body data的值;
		B)用來處理Content-Type: 爲 application/x-www-form-urlencoded編碼的內容,提交方式GET、POST;
		C) 該註解有三個屬性: value、required、defaultValue; value用來指定要傳入值的id名稱,required用來指示參數是否必須綁定;defaultValue設定默認值
	示例代碼:
	@Controller
	@RequestMapping("/pets")
	@SessionAttributes("pet")
	public class EditPetForm {
	    @RequestMapping(method = RequestMethod.GET)
	    public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
	        Pet pet = this.clinic.loadPet(petId);
	        model.addAttribute("pet", pet);
	        return "petForm";
	    }
	}

	3.2@RequestBody
	該註解常用來處理Content-Type: 不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等;
	它是通過使用HandlerAdapter 配置的HttpMessageConverters來解析post data body,然後綁定到相應的bean上的。
	因爲配置有FormHttpMessageConverter,所以也可以用來處理 application/x-www-form-urlencoded的內容,處理完的結果放在一個MultiValueMap<String, String>裏,這種情況在某些特殊需求下使用,詳情查看FormHttpMessageConverter api;
	示例代碼:
	@RequestMapping(value = "/something", method = RequestMethod.PUT)
	public void handle(@RequestBody String body, Writer writer) throws IOException {
	  writer.write(body);
	}
4、@SessionAttributes, @ModelAttribute
	4.1@SessionAttributes:
		該註解用來綁定HttpSession中的attribute對象的值,便於在方法中的參數裏使用。
		該註解有value、types兩個屬性,可以通過名字和類型指定要使用的attribute 對象;
	示例代碼:
		@Controller
		@RequestMapping("/editPet.do")
		@SessionAttributes("pet")
		public class EditPetForm {
		    // ...
		}
	4.2@ModelAttribute
		該註解有兩個用法,一個是用於方法上,一個是用於參數上;
			用於方法上時:  通常用來在處理@RequestMapping之前,爲請求綁定需要從後臺查詢的model;
			用於參數上時: 用來通過名稱對應,把相應名稱的值綁定到註解的參數bean上;要綁定的值來源於:
				A) @SessionAttributes 啓用的attribute 對象上;
				B) @ModelAttribute 用於方法上時指定的model對象;
				C) 上述兩種情況都沒有時,new一個需要綁定的bean對象,然後把request中按名稱對應的方式把值綁定到bean中。

		4.2.1用到方法上@ModelAttribute的示例代碼:
			// Add one attribute
			// The return value of the method is added to the model under the name "account"
			// You can customize the name via @ModelAttribute("myAccount")
			@ModelAttribute
			public Account addAccount(@RequestParam String number) {
			    return accountManager.findAccount(number);
			}
			這種方式實際的效果就是在調用@RequestMapping的方法之前,爲request對象的model裏put(“account”, Account);


		4.2.2用在參數上的@ModelAttribute示例代碼:
			@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
			public String processSubmit(@ModelAttribute Pet pet) {
			}
			首先查詢 @SessionAttributes有無綁定的Pet對象,
				若沒有則查詢@ModelAttribute方法層面上是否綁定了Pet對象,
				若沒有則將URI template中的值按對應的名稱綁定到Pet對象的各屬性上。

三、補充講解:
問題: 在不給定註解的情況下,參數是怎樣綁定的?
	通過分析AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter的源代碼發現,方法的參數在不給定參數的情況下:
	若要綁定的對象時簡單類型:  調用@RequestParam來處理的。  
	若要綁定的對象時複雜類型:  調用@ModelAttribute來處理的。
	這裏的簡單類型指java的原始類型(boolean, int 等)、原始類型對象(Boolean, Int等)、String、Date等ConversionService裏可以直接String轉換成目標對象的類型;

	RequestMappingHandlerAdapter中使用的參數綁定,代碼稍微有些不同,有興趣的同仁可以分析下,最後處理的結果都是一樣的。

	@RequestMapping ({"/", "/home"})
	    public String showHomePage(String key){
	        logger.debug("key="+key);
	        return "home";
	    }
	這種情況下,就調用默認的@RequestParam來處理。

    @RequestMapping (method = RequestMethod.POST)
    public String doRegister(User user){
        if(logger.isDebugEnabled()){
            logger.debug("process url[/user], method[post] in "+getClass());
            logger.debug(user);
        }
        return "user";
    }
	這種情況下,就調用@ModelAttribute來處理。

參考文檔:
1、 Spring Web Doc: 
spring-3.1.0/docs/spring-framework-reference/html/mvc.html
=========================================================================================================================================
3.@RequestMapping 使用須知
		使用@RequestMapping 註解映射請求路徑--即--你可以使用@RequestMapping註解來將請求URL
	映射到整個類上或某個特定的方法上,即@RequestMapping 既可以定義在類上,也可以定義方法上
		一般來說,類級別的註解負責將--一個特定(或符合某種模式)的請求路徑映射到一個控制器上,
	同時通過--方法級別的註解來--細化映射,即根據--特定的HTTP請求方法(GET、POST 方法等)、
	HTTP請求中--是否攜帶特定參數等條件,將請求映射到匹配的方法上

	具體配置方法:
	(1)映射單個URL
		@RequestMapping("") 或 @RequestMapping(value="")
	(2)映射多個URL
		@RequestMapping({"",""}) 或 @RequestMapping(value={"",""})
		路徑開頭是否加斜槓/均可,建議加上,如:@RequestMapping("/hello")
		
		@RequestMapping 一共有五種映射方式:
		1、標準URL 映射
			標準URL 映射是最簡單的一種映射,例如:
			@RequestMapping("/hello")  或  @RequestMapping({"/hello","/world"})
		2、Ant 風格的 URL 映射
			Ant 通配符有三種:
				?	匹配任何單字符
 				*	匹配任意數量的字符(含 0 個)
 				**	匹配任意數量的目錄(含 0 個)
			例如:(因爲/*是java中註釋,所以此處使用\代替/)
			(1)//@RequestMapping("\?\hello/")
			(2)//@RequestMapping("\*\hello")
			(3)//@RequestMapping("\**\hello")
		3、佔位符URL 映射
			URL 中可以通過一個或多個 {} 佔位符映射
			例如:@RequestMapping("/user/{userId}/show")
			可以通過@PathVariable("") 註解將佔位符中的值綁定到方法參數上
			代碼示例:
				//如果 URL 中的 userId 是純數字,那麼使用 @PathVariable
				//做綁定時,可以根據自己的需求將方法參數類型設置爲 Long、 Integer、String
				@RequestMapping("/user/{userId}/show")
				public ModelAndView show(@PathVariable("userId") Long userId) {
					// 創建 ModelAndView 對象,並設置視圖名稱
					ModelAndView mv = new ModelAndView("show");
					// 添加模型數據
					mv.addObject("msg", "User ID:" + userId);
					return mv;
				}

				注意:@PathVariable("") 不能簡寫爲 @PathVariable。因爲在正常編譯時,Java類反射對象不包含方法的參數名稱。
			如果在編	譯時將Debug打開(javac-debug=no),方法的參數名稱纔會記錄到類中,此時才能簡寫,但不建議簡寫。
				編譯時,打開Debug 的方法:
			打開Eclipse,Project->Properties->Java Compiler,勾選上Add variable attributes to generated class files … 即可
		4、限制請求方法的URL 映射
				在HTTP 請求中最常用的請求方法是 GET、POST,還有其他的
			一些方法,如:DELET、PUT、HEAD 等
			限制請求方法,例如:
				@RequestMapping(value="/hello", method=RequestMethod.POST)
			如需限制多個請求方法,以大括號包圍,逗號隔開即可,例如:
				method={RequestMethod.GET,RequestMethod.POST}
		5、限制請求參數的URL 映射
			限制請求參數來映射URL,例如:
				@RequestMapping(value="/user/show", params="userId")
				即請求中必須帶有userId 參數
			參數的限制規則如下:
				(1)params="userId" 請求參數中必須包含 userId
				(2)params="!userId" 請求參數中不能包含 userId
				(3)params="userId!=1" 請求參數中必須包含 userId,但不能爲 1
				(4)params={"userId","userName"} 必須包含 userId 和 userName 參數
			可以通過@RequestParam("") 註解將請求參數綁定到方法參數上
				@RequestMapping(value="/user/show",params="userId")
				public ModelAndView show(@RequestParam("userId") Long userId) {
					// 創建 ModelAndView 對象,並設置視圖名稱
					ModelAndView mv = new ModelAndView("show");
					// 添加模型數據
					mv.addObject("msg", "User ID:" + userId);
					return mv;
				}
			要注意@PathVariable("") 和 @RequestParam("") 的不同:
				@PathVariable("") 是將 URL 中佔位符處的值綁定到方法參數上
				@RequestParam("") 是將 URL 後的請求參數綁定到方法參數上
全文地址請點擊:https://blog.csdn.net/siwuxie095/article/details/79407097?utm_source=copy

========================================================================================================================

 */

	
//(出現400——方法參數數據類型不對應  只要方法裏面有相應參數它會自動去注入-不管注入幾次)

//1. 把內容寫到方法(HandlerMethod)參數中,SpringMVC 只要有這個內容,注入內容.
//2. 基本數據類型參數
	/**
	 * 2.1 默認保證參數名稱和請求中傳遞的參數名相同 
	 * @param name
	 * @param age
	 * @return
	 */
	@RequestMapping("demo2_1")//註解映射請求路徑
	public String demo2_1(String name,int age,HttpServletRequest req){
		String info = "demo2_1--"+name+"--"+age;
		System.out.println(info);
		req.setAttribute("demo2_1",info);
		return "/index.jsp";
	}
	/**
	 * 2.2 如果 請求參數名和方法參數名 不對應使用@RequestParam()賦值
	 * 	//@RequestParam()裏面有三個屬性
	 * 			value="" (默認屬性)	指定請求參數名  賦值給 方法中的參數名
	 * 			defaultValue="" 	參數設置默認值(防止沒有參數報500錯誤)
	 *			required=true(默認爲true) 強制要求必須有某個參數 
	 * @param name	前端的參數名爲name1
	 * @param age	前端的參數名爲age1
	 * @return
	 */
	@RequestMapping("demo2_2")
	public String demo2_2(@RequestParam(value="name1") String name,@RequestParam("age1") int age,HttpServletRequest req){
		String info = "demo2_2--"+name+"--"+age;
		System.out.println(info);
		req.setAttribute("demo2_2",info);
		return "/index.jsp";
	}
	
	/**
	 * 2.3 如果方法參數是基本數據類型(不是封裝類)可以通過@RequestParam 設置默認值.
	 *	2.3.1 使用@RequestParam(defaultValue=" ")防止沒有參數時   報500的錯誤
	 *		沒有值就使用默認值--有值就使用傳進來的值
	 * @param pageSize		
	 * @param pageNumber	
	 * @return
	 */
	@RequestMapping("demo2_3")
	public String demo2_3(@RequestParam(defaultValue="2") int pageSize,@RequestParam(defaultValue="1") int pageNumber,HttpServletRequest req){
		String info = "demo2_3--pageSize:"+pageSize+"--pageNumber:"+pageNumber;
		System.out.println(info);
		req.setAttribute("demo2_3",info);
		return "/index.jsp";
	}
	
	/**
	 * 2.4 如果強制要求必須有某個參數 
	 * @param name
	 * @return
	 */
	@RequestMapping("demo2_4")
	public String demo2_4(@RequestParam(required=true) String name,HttpServletRequest req){
		String info = "demo2_4--name是SQL的查詢條件,必須要傳遞name參數:"+name;
		System.out.println(info);
		req.setAttribute("demo2_4",info);
		return "/index.jsp";
	}
	

//3.HandlerMethod 中參數是對象類型
	/**
	 * 3.1請求參數名和對象中屬性名對應(get/set 方法) 
	 * 		只要方法裏面有相應參數它會自動去注入-不管注入幾次
	 * @param peo	People對象有屬性name和age(屬性名與請求參數名對應)並且有相應的get/set方法
	 * @param name	
	 * @param age
	 * @param req	原生servlet裏面的東西在這裏都可以使用
	 * @param resp
	 * @return
	 */
	@RequestMapping("demo3_1")
	public String demo3_1(People peo,HttpServletRequest req) {
		String info = "demo3_1--"+peo;
		System.out.println(info);
		req.setAttribute("demo3_1",info);
		return "/index.jsp";
	}
	@RequestMapping("demo3_2")
	public String demo3_2(People peo,String name,int age,HttpServletRequest req,HttpServletResponse resp) {
		String info = "demo3_2--"+peo+"--"+name+"--"+age;
		System.out.println(info);
		req.setAttribute("demo3_2",info);
		return "/index.jsp";
	}
	
//4. 請求參數中包含多個同名參數的獲取方式
	/**
	 * 4.1 複選框傳遞的參數就是多個同名參數
	 * 		需要使用@RequestParam("同名的參數名") 將同名參數的數據注入到list裏面
	 * @param name
	 * @param age
	 * @param abc
	 * @return
	 */
	@RequestMapping("demo4_1")
	public String demo4_1(String name,int age,@RequestParam("hover") List<String> list,HttpServletRequest req) {
		String info = "demo4_1--"+name+"--"+age+"--"+list;
		System.out.println(info);
		req.setAttribute("demo4_1",info);
		return "/index.jsp";
	}
	
//5. 請求參數中 對象.屬性 格式
	/**
	 * 例如:Demo demo 中有屬性  People peo
	 * 		demo.name=123   先去demo再去Demo的屬性people的屬性name
	 * @param demo
	 * @return
	 */
	@RequestMapping("demo5_1")
	public String demo5_1(Demo demo,HttpServletRequest req) {
		String info = "demo5_1--demo"+demo;
		System.out.println(info);
		req.setAttribute("demo5_1",info);
		return "/index.jsp";
	}
//6. 在請求參數中傳遞集合對象類型參數
	/**
	 * 例如:Demo2 demo 中有屬性 List<People> peo
	 * 		peo[0].name=123 
	 * 		peo[1].name=123
	 * @param demo
	 * @return
	 */
	@RequestMapping("demo6_1")
	public String demo6_1(Demo2 demo,HttpServletRequest req) {
		System.out.println("demo6_1--demo2"+demo);
		String info = "demo6_1--demo2"+demo;
		System.out.println(info);
		req.setAttribute("demo6_1",info);
		return "/index.jsp";
	}
//7.0 restful 傳值方式. ---前傳
	@RequestMapping("demo7_0")
	public String demo7_0(String name,int age,HttpServletRequest req) {
		String info = "demo7_0--name:"+name+"--age:"+age;
		System.out.println(info);
		req.setAttribute("demo7_0",info);
		return "/index.jsp";
	}
//7 restful 傳值方式. ---後傳-----------------------------------------推薦使用這種傳值方式
	/**
	 * 7.1 簡化 jsp 中參數編寫格式
	 * 7.2 在 jsp 中設定特定的格式
	 *    <a href="demo7_1/abc/123">跳轉</a>
	 * 7.3 在控制器中
	 *	7.3.1 在@RequestMapping 中一定要和請求格式對應
	 *	7.3.2 {名稱} 中名稱自定義名稱
	 *	7.3.3 @PathVariable 註解,其用來獲取請求路徑(url)中的動態參數
	 *			獲取@RequestMapping 中內容,默認按照方法參數名稱去尋找. 
	 * @param name
	 * @param age
	 * @return
	 */
	@RequestMapping("demo7_1/{name}/{age1}") 
	public String demo7_1(@PathVariable String name,@PathVariable("age1") int age,HttpServletRequest req) {
		String info = "demo7_1--name:"+name+"--age:"+age;
		System.out.println(info);
		req.setAttribute("demo7_1",info);
		return "/index.jsp";
	}
	
//四.跳轉方式
//	1. 默認跳轉方式請求轉發.
//	2. 設置返回值字符串內容
//	2.1 添加 redirect:資源路徑 重定向
//	2.2 添加 forward:資源路徑 或省略 forward: 轉發
	@RequestMapping("/demo8_1")
	public String demo8_1(HttpServletRequest req) {
		String info = "轉發";
		System.out.println(info);
		req.setAttribute("demo8_1",info);
		return "forward:/index.jsp";
	}
	@RequestMapping("/demo8_2")
	public String demo8_2() {
		System.out.println("重定向");
		return "redirect:/main.jsp";
	}
	
	
//直接在頁面中輸出     
//方法一
	@RequestMapping("/demo9_1")
	public void demo9_1(HttpServletResponse resp) throws IOException {
		PrintWriter out = resp.getWriter();
		out.println("demo9_1");
		out.flush();
		out.close();
	}
//方法二
/**
六@ResponseBody 寫在方法上	一般用於異步獲取數據
1. 在方法上只有@RequestMapping 時,無論方法返回值是什麼認爲需要跳轉
2. 在方法上添加@ResponseBody(恆不跳轉)
	2.1 如果返回值滿足 key-value 形式(對象或 map)
		2.1.1 把響應頭設置爲 application/json;charset=utf-8
		2.1.2 把轉換後的內容輸出流的形式響應給客戶端.
	2.2 如果返回值不滿足 key-value,例如返回值爲 String
		2.2.1 把相應頭設置爲 text/html
		2.2.2 把方法返回值以流的形式直接輸出.
		2.2.3 如果返回值包含中文,出現中文亂碼
			2.2.3.1 produces 表示響應頭中 Content-Type 取值.
		@RequestMapping(value="demo12",produces="text/html;charset=utf-8")
3. 底層使用Jackson進行json轉換,在項目中一定要導入jackson的jar
	3.1spring4.1.6 對 jackson 不支持較高版本,jackson2.7 無效

https://blog.csdn.net/ff906317011/article/details/78552426
4. @Responsebody 註解表示該方法的返回的結果直接寫入 HTTP 響應正文(ResponseBody)中,
一般在——異步獲取數據 時使用,通常是在使用 @RequestMapping 後,返回值通常解析爲跳轉路徑,
加上 @Responsebody 後返回結果--不會被解析爲跳轉路徑,而是直接寫入HTTP 響應正文中。
作用:
	該註解用於將Controller的方法返回的對象,
	通過適當的HttpMessageConverter轉換爲指定格式後,寫入到Response對象的body數據區。
使用時機:
	返回的數據不是html標籤的頁面,而是其他某種格式的數據時(如json、xml等)使用;


七@RequestBody	寫在方法參數中前面
@RequestBody 註解則是--將HTTP請求正文--插入方法中,
	使用適合的 HttpMessageConverter 將請求體寫入某個對象。
作用:
	1)該註解用於讀取Request請求的body部分數據,
		使用系統默認配置的HttpMessageConverter進行解析,
		然後把相應的數據綁定到要返回的對象上;
	2)再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。

使用時機:
A) GET、POST方式提時, 根據request header Content-Type的值來判斷:
	application/x-www-form-urlencoded,可選(即非必須,因爲這種情況的數據
		@RequestParam,@ModelAttribute也可以處理,當然@RequestBody也能處理);
	multipart/form-data,不能處理(即使用@RequestBody不能處理這種格式的數據);
	其他格式,必須(其他格式包括application/json,application/xml等。
		這些格式的數據,必須使用@RequestBody來處理);
B) PUT方式提交時, 根據request header Content-Type的值來判斷:
	application/x-www-form-urlencoded, 必須;multipart/form-data, 不能處理;其他格式, 必須;
	說明:request的body部分的數據編碼格式由header部分的Content-Type指定;
	@RequestMapping(value = "user/login")
	@ResponseBody
	// 將ajax(datas)發出的請求寫入 User 對象中
	public User login(@RequestBody User user) {   
	// 這樣就不會再被解析爲跳轉路徑,而是直接將user對象寫入 HTTP 響應正文中
	    return user;    
	}

 */
	// 是key-value形式
	@RequestMapping(value="demo9_2")
	@ResponseBody
	public People demo9_2() throws IOException {
		People p = new People();
		p.setName("張三");
		p.setAge(12);
		return p;
	}
	// 不是key-value形式  有中文
	@RequestMapping(value="demo9_3",produces="text/html;charset=utf-8")
	@ResponseBody
	public String demo9_3() throws IOException {
		People p = new People();
		p.setName("張三");
		p.setAge(12);
		return "中文";
	}
	
	
//當使用自定義視圖解析器的時候	其他案例:
/*
<!-- 自定義視圖解析器(默認springmvc有不配置也可以) 
			如果方法返回值前面有(forward:)或(redirect:)就不再執行自定義視圖解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalR esourceViewResolver"> 
		<property name="prefix" value="/"></property> 
		<property name="suffix" value=".jsp"></property> 
</bean>

	@RequestMapping("/demo9")
	public  String demo9() {
		return "forward:/demo10";
	}
	@RequestMapping("/demo10")
	public  String demo10() {
		System.out.println("demo10");
		return "main";
	}
 */
}

 

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 掃描註解 -->
	<context:component-scan base-package="com.bjsxt.controller"></context:component-scan>
	<!-- 註解驅動 -->
	<!-- org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping -->
	<!-- org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter -->
	<mvc:annotation-driven></mvc:annotation-driven>
	<!-- 靜態資源    mapping中 * 是子文件   **是下面的所有的文件 -->
	<!-- 	location是請求路徑對應的真實路徑		mapping是請求的地址    -->
	<!-- 	mapping中**是什麼就向location中找什麼 -->
	<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
	<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
	<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
	
	<!-- 自定義視圖解析器(默認springmvc有不配置也可以) 
			如果方法返回值前面有(forward:)或(redirect:)就不再執行自定義視圖解析器-->
	<!-- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalR esourceViewResolver"> 
		<property name="prefix" value="/"></property> 
		<property name="suffix" value=".jsp"></property> 
	</bean> -->
</beans>

<!-- 
一.SpringMVC 簡介
	1.SpringMVC 中重要組件
		1.1 DispatcherServlet: 前端控制器,接收所有請求(如果配置/不包含 jsp)		配置在web.xml  Filter攔截所有請求
		1.2 HandlerMapping: 映射器——解析請求格式的.判斷希望要執行哪個具體的方法.	
		1.3 HandlerAdapter: 適配器——負責調用具體的方法.
		1.4 ViewResovler:視圖解析器.解析結果,準備跳轉到具體的物理視圖
	
	 適配器和視圖解析器有SpringMVC默認的,不配置也可以運行(也可以配置)	
	
	3.Spring 容器和 SpringMVC 容器的關係(父子容器)
		3.1 Spring 容器和 SpringMVC 容器是——父子容器.
			3.1.1 SpringMVC 容器中能夠調用 Spring 容器的所有內容.

二.SpringMVC 環境搭建
	1. 導入 jar  其他的加上(spring-mvc.jar)
	2. 在 web.xml 中配置前端控制器 DispatcherServlet
		2.1 如果不配置 <init-param> 會在/WEB-INF/<servlet-name>-servlet.xml 
——配置前端控制器  servlet分發器
<servlet>
	<servlet-name>jqk</servlet-name>
	——spring-mvc.jar中     DispatcherServlet(servlet分發器)
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	——修改並設置 配置文件的路徑和名稱
	——如果不配置 <init-param> 會在 /WEB-INF/<servlet-name>-servlet.xml
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:springmvc.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>jqk</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

	3. 在 src 下新建 springmvc.xml
		3.1 引入 xmlns:mvc 命名空間 
——掃描註解
<context:component-scan base-package="com.bjsxt.controller"></context:component-scan>
——註解驅動
<mvc:annotation-driven></mvc:annotation-driven>
——靜態資源    mapping中 * 是子文件   **是下面的所有的文件
	——location是請求路徑對應的真實路徑		mapping是請求的地址 
	——mapping中**是什麼就向location中找什麼
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>

	4. 編寫控制器類
@Controller
public class DemoController {
	@RequestMapping("demo")
	public String demo(){
		System.out.println("執行demo");
		return "main.jsp";
	}
	@RequestMapping("demo2")
	public String demo2(){
		System.out.println("demo2");
		return "main1.jsp";
	}
}

三.字符編碼過濾器
	1.在 web.xml 中配置 Filter:
設置字符編碼過濾器(相當於 req.setCharacterEncoding("utf-8")) 
<filter>
	<filter-name>encoding</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>utf-8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encoding</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

四.傳參  (出現400——方法參數數據類型不對應  只要方法裏面有相應參數它會自動去注入-不管注入幾次)
	1. 把內容寫到方法(HandlerMethod)參數中,SpringMVC 只要有這個內容,注入內容.
	2. 基本數據類型參數
		2.1 默認保證參數名稱和請求中傳遞的參數名相同 
@Controller 
public class DemoController { 
	@RequestMapping("demo") 
	public String demo(String name,int age){ 
		System.out.println("執行 demo"+" "+name+" "+age);
		return "main.jsp";
	}
}
		2.2 如果請求參數名和方法參數名不對應使用@RequestParam()賦值
@RequestMapping("demo") 
public String demo(@RequestParam(value="name1") String name,@RequestParam(value="age1")int age){ 
	System.out.println("執行 demo"+" "+name+" "+age); 
	return "main.jsp"; 
}
		2.3 如果方法參數是基本數據類型(不是封裝類)可以通過
			@RequestParam 設置默認值.
			2.3.1 防止沒有參數時 500
@RequestMapping("page") 
public String page(@RequestParam(defaultValue="2") int pageSize,@RequestParam(defaultValue="1") int pageNumber){ 
	System.out.println(pageSize+" "+pageNumber); 
	return "main.jsp"; 
}
		2.4 如果強制要求必須有某個參數 
@RequestMapping("demo2") 
public String demo2(@RequestParam(required=true) String name){ 
	System.out.println("name 是 SQL 的查詢條件,必須要傳 遞 name 參數"+name); 
	return "main.jsp"; 
}
	3. HandlerMethod 中參數是對象類型
		3.1 請求參數名和對象中屬性名對應(get/set 方法) 
@RequestMapping("demo4") 
public String demo4(People peo){ 
	return "main.jsp"; 
}
	4. 請求參數中包含多個同名參數的獲取方式
		4.1 複選框傳遞的參數就是多個同名參數
@RequestMapping("demo5") 
public String demo5(String name,int age,@RequestParam("hover")List<String> abc){ 
	System.out.println(name+" "+age+" "+abc); 
	return "main.jsp"; 
}
	5. 請求參數中對象.屬性格式
		5.1 jsp 中代碼 
			<input type="text" name="peo.name"/> 
			<input type="text" name="peo.age"/>
		5.2 新建一個類
			5.2.1 對象名和參數中點前面名稱對應 public class Demo { private People peo;
		5.3 控制器
@RequestMapping("demo6") 
public String demo6(Demo demo){ 
	System.out.println(demo); 
	return "main.jsp"; 
}
	6. 在請求參數中傳遞集合對象類型參數
		6.1 jsp 中格式 <input type="text" name="peo[0].name"/> <input type="text" name="peo[0].age"/> <input type="text" name="peo[1].name"/> <input type="text" name="peo[1].age"/>
		6.2 新建類 
public class Demo {
	private List<People> peo;
		6.3 控制器 
@RequestMapping("demo6") 
public String demo6(Demo demo){ 
	System.out.println(demo); 
	return "main.jsp"; 
}
	7. restful 傳值方式.
		7.1 簡化 jsp 中參數編寫格式
		7.2 在 jsp 中設定特定的格式
			<a href="demo8/123/abc">跳轉</a>
		7.3 在控制器中
			7.3.1 在@RequestMapping 中一定要和請求格式對應
			7.3.2{名稱} 中名稱自定義名稱
			7.3.3 @PathVariable 獲取@RequestMapping 中內容,
				默認按照	方法參數名稱去尋找. 
@RequestMapping("demo8/{id1}/{name}") 
public String demo8(@PathVariable String name,@PathVariable("id1") int age){ 
	System.out.println(name +" "+age); 
	return "/main.jsp"; 
}
四.跳轉方式
	1. 默認跳轉方式——請求轉發.
	2. 設置返回值字符串內容
		2.1 添加 redirect:資源路徑 重定向	  
				例如:return "redirect:/main.jsp";
		2.2 添加 forward:資源路徑 或省略 forward: 轉發
				例如:return "forward:/main.jsp"; 或者 return "";
五.視圖解析器
	1. SpringMVC 會提供默認視圖解析器.
	2. 程序員自定義視圖解析器 
		<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalR esourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean>
	3. 如果 希望不執行自定義視圖解析器,在方法返回值前面添加
			forward:或 redirect:即可		
六.@ResponseBody
	1. 在方法上只有@RequestMapping 時,無論方法返回值是什麼認爲需要跳轉
	2. 在方法上添加@ResponseBody(恆不跳轉)
		2.1 如果返回值滿足 key-value 形式(對象或 map)
			2.1.1 把響應頭設置爲 application/json;charset=utf-8
			2.1.2 把轉換後的內容輸出流的形式響應給客戶端.
		2.2 如果返回值不滿足 key-value,例如返回值爲 String
			2.2.1 把相應頭設置爲 text/html
			2.2.2 把方法返回值以流的形式直接輸出.
			2.2.3 如果返回值包含中文,出現中文亂碼
			2.2.3.1produces 表示響應頭中 Content-Type 取值.
				@RequestMapping(value="demo12",produces="text/html; charset=utf-8")
				@ResponseBody 
				public String demo12() throws IOException{ 
					People p = new People(); 
					p.setAge(12);
					p.setName("張三"); 
					return "中文";
				}
	3. 底層使用Jackson進行json轉換,在項目中一定要導入jackson的jar
		3.1 spring4.1.6 對 jackson 不支持較高版本,jackson2.7 無效.	
 -->

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                       
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<!-- 配置前端控制器  servlet分發器-->
	<servlet>
		<servlet-name>jqk</servlet-name>
		<!-- spring-mvc.jar中     DispatcherServlet(servlet分發器) -->
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 修改並設置 配置文件的路徑和名稱 -->
		<!-- 	如果不配置 <init-param> 會在 /WEB-INF/<servlet-name>-servlet.xml  -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>jqk</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
	<!-- 設置字符編碼過濾器(相當於 req.setCharacterEncoding("utf-8")) -->
	<filter>
		<filter-name>encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encoding</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

com.pojo實體類

 

package com.bjsxt.pojo;
public class Demo {	
	private People peo;
	public People getPeo() {
		return peo;
	}
	public void setPeo(People peo) {
		this.peo = peo;
	}
	@Override
	public String toString() {
		return "Demo [peo=" + peo + "]";
	}
}
========================================================
package com.bjsxt.pojo;
import java.util.List;
public class Demo2 {
	private List<People> peo;
	public List<People> getPeo() {
		return peo;
	}
	public void setPeo(List<People> peo) {
		this.peo = peo;
	}
	@Override
	public String toString() {
		return "Demo2 [peo=" + peo + "]";
	}
}
========================================================
package com.bjsxt.pojo;
public class People {
	private String name;
	private int age;
	@Override
	public String toString() {
		return "People [name=" + name + ", age=" + age + "]";
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}                                                

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章