普通浏览器:只支持get post方式:其他请求方式 如DELETE,PUT 有过滤器实(HiddenHttpMethodFilter)
首先要配置过滤器
当满足约定时修改请求
1.
<input type = "hidden" name = "_method" value = "delete|put"/>
2.请求方式为post
分发器中处理请求
可以存在多个一样的requestMapping,用请求方式来区分
实现:过滤器将原始的请求 request 加入新的请求方式DELETE,并将原始请求转为requestToUse 请求(request+DELETE)
最后将requestToUse 放入请求链中,后续使用request 实际上用的是改造后的requestToUse
@RequestMapping(value = "select/{id}",method=RequestMethod.GET)
public String select(@PathVariable("id") int id) {
System.out.println("查:"+id);
//有service实现真正的功能
return null;
}
//增
@RequestMapping(value = "add/{id}",method=RequestMethod.POST)
public String add(@PathVariable("id") int id) {
System.out.println("增:"+id);
//有service实现真正的功能
return null;
}
//删
@RequestMapping(value = "delete/{id}",method=RequestMethod.DELETE)
public String delete(@PathVariable("id") int id) {
System.out.println("删:"+id);
//有service实现真正的功能
return null;
}
//改
@RequestMapping(value = "update/{id}",method=RequestMethod.PUT)
public String update(@PathVariable("id") int id) {
System.out.println("改:"+id);
//有service实现真正的功能
return null;
}
<form method = "post" action = "delete/1234">
<input type = "hidden" name = "_method" value = "DELETE"/>
<input type = "submit" value = "删"/>
</form><br/>
<form method = "post" action = "update/1234">
<input type = "hidden" name = "_method" value = "POST"/>
<input type = "submit" value = "改"/>
</form><br/>
接收参数:
用@requestParam 获取参数,并指定保存的变量
用@requestHeader获取请求头信息,并将其保存在指定变量中
@CookieValue
前置知识:服务端在接收客户端第一次请求时,会给该客户分配一个session(该session包含一个sessionid)
并且服务端会在第一次响应客户端时,将该sessionId赋值给JSESSIONID,并传递给客户端的cookie中
使用 POJO 对象绑定请求参数值
Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。
//接收参数
//当接收设置两个值,但是前端只传入一个值,会报错,但可以添加required属性,指定该值不是必要的
//可指定默认值
//获取头信息(key=value)@RequestHeader
@RequestMapping(value = "params")
public String params(@RequestParam("uname") String name,
@RequestParam(value="uage",required=false,defaultValue="12") String age
,@RequestHeader("Accept-Language") String hander,@CookieValue("JSESSIONID") String cookie
) {
System.out.println(name);
System.out.println(age);
System.out.println(hander);
System.out.println(cookie);
//有service实现真正的功能
return null;
}
}
小结:
SpringMVC处理各种参数的流程:
请求:前端发请求a -> @RequestMapping(“a”)
处理请求中各种参数:
@RequestMapping(“a”)
public String aa(@xxx注解(“xxx”) 类型 变量名){
}
在SpringMVC中使用原生态的Servlet
MVC 的 Handler 方法可以接受
哪些 ServletAPI 类型的参数
• HttpServletRequest
• HttpServletResponse
• HttpSession
• java.security.Principal
• Locale
• InputStream
• OutputStream
• Reader
• Writer
@RequestMapping("xxx")
public String entiry(HttpServletRequest request,HttpServletResponse response) {
request.getParameter("");
return null;
}
处理模型数据
• Spring MVC 提供了以下几种途径输出模型数据:
– ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加模型数据
– Map 及 Model: 入参为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
– @SessionAttributes: 将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性
– @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型中
ModelAndView
• 控制器处理方法的返回值如果为 ModelAndView, 则其既包含视图信息,也包含模型数据信息。
@Controller
public class MAndVHandler {
//ModelAndView:既有页面又有数据
@RequestMapping(value = "testMV")
public ModelAndView testMV(){
ModelAndView mv = new ModelAndView("ModelAndView");//指定返回的页面
Person p = new Person();
p.setName("xxx");
mv.addObject("person", p);//相当于request.setAttribute()
return mv;
}
}
Map 及 Model
• Spring MVC 在内部使用了一个org.springframework.ui.Model 接口存储模型数据
• 具体步骤 – Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
– 如果方法的入参为 Map 或 Model 类 型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据
ModelMap
@RequestMapping(value = "testMM")
public String ModelMap(ModelMap mm){
Person p = new Person();
p.setName("xxx");
mm.addAttribute("person", p);//放在request域中
return "ModelAndView";
}
Model
@RequestMapping(value = "testModel")
public String Model(Model model){
Person p = new Person();
p.setName("xxx");
model.addAttribute("person", p);
return "ModelAndView";
}
Map
@RequestMapping(value = "testMap")
public String Map(java.util.Map<String,Object> map){
Person p = new Person();
p.setName("xxx");
map.put("person",p);
return "ModelAndView";
}
session
如何将上述数据保存到session中?
给类添加注解@SessionAttributes
• 若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes, Spring MVC 将在模型中对应的属性暂存到 HttpSession 中。
• @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中 – @SessionAttributes(types=User.class) 会将隐含模型中所有类型为User.class 的属性添加到会话中。
– @SessionAttributes(value={“user1”, “user2”})
– @SessionAttributes(types={User.class, Dept.class})
– @SessionAttributes(value={“user1”, “user2”}, types={Dept.class})
//指定参数名
@SessionAttributes("person,xxx")//当在要在request中存放person数据,则同时将该对象 放入session域中
//指定参数类型
@SessionAttributes(type = {Person.class,Address.class})//当在要在request中存放person类型的数据,则
同时将该对象 放入session域中
参数处理
修改传入方法的参数@ModelAttribute
1.经常在更新时使用
2.在不改变原有代码的基础上,加入新方法
任何一次请求前,都先执行@ModelAttribute修饰的方法
在请求该类的各个方法前 均被执行的设计是基于一个思想:一个控制器对应一个功能
约定:map的key就是首字母小写的方法参数类型,不一致时使用注解注释(一致时不用加)
map保存传入方法的数据
@ModelAttribute//任何一次请求前,都先执行@ModelAttribute修饰的方法
public void query(Person person,java.util.Map<String,Object> map) {
//Dao层操作
map.put("per", person);//约定:map的key就是首字母小写的方法参数类型,不一致时使用注解注释(一致时不用加)
}
//修改方法
@RequestMapping("update")
public String update(@ModelAttribute("per")Person person) {
person.setName("xxx");
return "ModelAndView";
}
由@SessionAttributes引发的异常
org.springframework.web.HttpSessionRequiredException: Session attribute ‘user’ required - not found in session
• 如果在处理类定义处标注了@SessionAttributes(“xxx”),则尝试从会话中获取该属性,并将其赋给该入参,然后再用请求消息填充该入参对象。如果在会话中找不到对应的属性,则抛出HttpSessionRequiredException 异常
处理:由ModelAttribute预处理入参