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;
}
}