目录
1、SpringMVC介绍
2、SpringMVC原理
3、SpringMVC优势
4、创建工程
【1】依赖
【2】web.xml配置文件
【3】Spring配置文件applicationContext.xml
【4】建SpringMVC的配置文件springmvc.xml
【5】配置视图解析器
【6】两个问题
4、SpringMVC工作流程
【1】工作流程分析
【2】SpringMVC组件
【3】@RequestMapping 注解
5、处理器方法的参数
6、如何处理中文乱码
7、页面导航的方式
【1】转发到一个jsp页面
【2】重定向到一个jsp页面
【3】重定向或者转发到控制器
8、RESTful介绍
【1】API设计
【2】HTTP状态码
【3】案例
【4】查询
【5】配置过滤器
SpringMVC 也叫 Spring web mvc 。是 Spring 内置的一个 MVC 框架,在 Spring3.0 后发布。 SpringMVC框架解决了 WEB 开发中常见的问题 ( 参数接收、文件上传、表单验证等等 ) ,而且使用简单,与 Spring 无 缝集成。支持 RESTful 风格的 URL 请求。采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性 和灵活性。
servlet 是 java 进行 web 开发的标准,既然 springMVC 是对servlet 的封装,那么很显然 SpringMVC 底层就是 Servlet , SpringMVC 就是对 Servlet 进行深层次的封装。
1 、基于 MVC 架构,功能分工明确。解决页面代码和后台代码的分离。2 、简单易用。 SpringMVC 也是轻量级的, jar 很小。不依赖的特定的接口和类就可以开发一个注解的 SpringMVC 项目。3 、作 为 Spring 框 架 一 部 分 , 能 够 使 用 Spring 的 IoC 和 AOP 。 方 便 整 合 MyBatis,Hiberate,JPA 等 其他框架。4 、 springMVC 的注解强大易用。
4.0.0
com.qinluyu
SpringMVC01
1.0-SNAPSHOT
war
org.springframework
spring-webmvc
5.2.7.RELEASE
javax.servlet
javax.servlet-api
4.0.1
provided
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
/
9090
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
dispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
dispatcherServlet
/
1.Spring 容器中不能扫描所有 Bean 嘛?不可以。当用户发送的请求达到服务端后,会寻找前端控制器 DispatcherServlet 去处理,只在SpringMVC 容器中找,所以 Controller 必须在 SpringMVC 容器中扫描。2.SpringMVC 容器中可以扫描所有 Bean 嘛?可以。可以在 SpringMVC 容器中扫描所有 Bean 。但是实际开发中一般不会这么做,原因如下:( 1 )为了方便配置文件的管理( 2 )未来在 Spring+SpringMVC+Mybatis 组合中,要写的配置内容很多,一般都会根据功能分开编写
(1 )用户通过浏览器发送请求到中央调度器 DispatcherServlet 。(2)中央调度器直接将请求转给处理器映射器HandleMapping 。(3 )处理器映射器 HandleMapping 会根据请求,找到负责处理该请求的处理器,并将其封装为处理器执行链 HandlerExecutionChina后返回给中央调度器DispatcherServlet。(4)中央调度器DispatcherServlet根据处理器执行链中的处理器,找到能够执行该处理器的处理器适配器 HandlerAdaptor 。(5 )处理器适配器 HandlerAdaptor 调用执行处理器 Controller 。(6 )处理器 Controller 将处理结果及要跳转的视图封装到一个对象 ModelAndView 中,并将其返回给 处理器适配器 HandlerAdaptor 。(7)处理器适配器直接将结果返回给中央调度器DispatcherServlet。(8)中央调度器调用视图解析器,将 ModelAndView 中的视图名称封装为视图对象。(9 )视图解析器 ViewResolver 将封装了的视图 View对象返回给中央调度DispatcherServlet.( 10)中央调度器DispatcherServlet调用视图对象,让其自己进行渲染,即进行数据填充,形成响应对 象。( 11)中央调度器响应浏览器。
1.DispatcherServlet :前端控制器 , 也称为中央控制器或者核心控制器。2.HandlerMapping :处理器映射器3.Handler :处理器4.HandlAdapter :处理器适配器5.ViewResolver :视图解析器
@RequestMapping(value = "add.do",method = RequestMethod.GET)
public ModelAndView addTeam(){
System.out.println("TeamController----addTeam---");
ModelAndView mv=new ModelAndView();
mv.setViewName("team/add");// 映射成为物理资源路径:/jsp/team/add.jsp
return mv;
}
@RequestMapping(value = "update.do",method = RequestMethod.POST)
public ModelAndView updateTeam(){
System.out.println("TeamController----updateTeam---");
ModelAndView mv=new ModelAndView();
mv.setViewName("team/update");//映射成为物理资源路径:/jsp/team/update.jsp
return mv;
}
@RequestMapping("hello.do")
public ModelAndView hello(){
System.out.println("TeamController----add---");
teamService.add();
ModelAndView mv=new ModelAndView();
mv.addObject("teamName","湖人");//相当于request.setAttrubuite("teanName","湖人");
mv.setViewName("index");//未来经过springmvc的视图解析器处理,转换成物理资源路径,相当于request.getRequestDispatcher("index.jsp").forward();
//经过InternalResourceViewResolver对象的处理之后加上前后缀就变为了 /jsp/index.jsp
return mv;
}
@RequestMapping的method属性,用来对被注解方法所处理请求的提交方式进行限制,即只有满足method 属性指定的提交方式的请求,才会执行该被注解方法。
1 直接使用方法的参数逐个接收2 使用对象接收多个参数3 请求参数和方法名称的参数不一致4 使用 HttpServletRequest 对象获取参数5 直接使用 URL 地址传参6 获取日期类型的参数7 获取数组类型的参数8 获取集合类型的参数
//8、获取集合类型的参数: 简单类型的可以通过@RequestParam注解实现;对象集合不支持直接获取,必须封装在类中,作为一个属性操作
@RequestMapping("test08")
public ModelAndView test08(@RequestParam("teamName") List nameList){
System.out.println("test08-----------------");
for (String s : nameList) {
System.out.println(s);
}
return new ModelAndView("ok");
}
@RequestMapping("test09")
public ModelAndView test09(QueryVO vo){
System.out.println("test09-----------------");
for (Team team : vo.getTeamList()) {
System.out.println(team);
}
return new ModelAndView("ok");
}
//7、获取数组类型的参数
@RequestMapping("test07")
public ModelAndView test07(String[] teamName,HttpServletRequest request){
System.out.println("test07-----------------");
//方式1:
for (String s : teamName) {
System.out.println(s);
}
System.out.println("---------------");
//方式2:
String[] teamNames = request.getParameterValues("teamName");
for (String name : teamNames) {
System.out.println(name);
}
return new ModelAndView("ok");
}
//6、获取日期类型的参数:实体类中的对应的属性上必须有注解 @DateTimeFormat(pattern = "yyyy-MM-dd")
@RequestMapping("test06")
public ModelAndView test06(Team team){
System.out.println("test06-----------------");
System.out.println(team);
return new ModelAndView("ok");
}
//5、直接使用URL地址传参: 借助@PathVariable 注解
// 例如http://localhost:8080/param/test05/1001/lacker/las
@RequestMapping("test05/{id}/{name}/{loc}")
public ModelAndView test05(@PathVariable("id") Integer teamId,
@PathVariable("name") String teamName,
@PathVariable("loc") String teamLocation){
System.out.println("test05-----------------");
System.out.println(teamId);
System.out.println(teamName);
System.out.println(teamLocation);
return new ModelAndView("ok");
}
//4、使用HttpServletRequest 对象获取参数:跟原来的javaWeb项目中使用的方式是一样的
@RequestMapping("test04")
public ModelAndView test04(HttpServletRequest request){
System.out.println("test04-----------------");
String teamId = request.getParameter("teamId");
String teamName = request.getParameter("teamName");
String location = request.getParameter("location");
if(teamId!=null)
System.out.println(Integer.valueOf(teamId));
System.out.println(teamName);
System.out.println(location);
return new ModelAndView("ok");
}
//3、请求参数和方法名称的参数不一致:使用@RequestParam进行矫正,
// value属性表示请求中的参数名称
// required属性表示参数是否是必须的:true:必须赋值,否则报出400错;false:可以不赋值,结果就是null
@RequestMapping("test03")
public ModelAndView test03(@RequestParam(value = "teamId",required = false) Integer id,
@RequestParam(value = "teamName",required = true) String name,
@RequestParam("location") String loc){
System.out.println("test03-----------------");
System.out.println(id);
System.out.println(name);
System.out.println(loc);
return new ModelAndView("ok");
}
//2、使用对象接收多个参数:要求用户请求中携带的参数名称必须是实体类中的属性保持一致,否则就获取不到
@RequestMapping("test02")
public ModelAndView test02(Team team){
System.out.println("test02-----------------");
System.out.println(team);
return new ModelAndView("ok");
}
/**
* 1、直接使用方法的参数逐个接收:方法的参数名称必须与用户请求中携带的参数名称保持一致,否则就获取不到
* 好处:不需要类型转换
*/
@RequestMapping("test01")
public ModelAndView test01(Integer teamId,String teamName,String teamLocation){
System.out.println("test01-----------------");
System.out.println(teamId);
System.out.println(teamName);
System.out.println(teamLocation);
return new ModelAndView("ok");
}
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceRequestEncoding
true
forceResponseEncoding
true
characterEncodingFilter
/*
页面导航分为两种: 1 、转发 2 、重定向springMVC 有以下两种方式实现页面的转发或重定向:1 、返回字符串2 、使用 ModelAndView在 SpringMVC 中两种导航进行页面导航的时候使用不同的前缀指定转发还是重定向前缀: 转发: forward:url 默认重定向: redirect:url
//1、转发到一个JSP页面
//使用字符串转发
@RequestMapping("test01-1")
public String test011(HttpServletRequest request){
System.out.println("test01-1-------------");
request.setAttribute("teamName","lacker");
//return "ok";//默认方式:由视图解析器处理之后将逻辑视图转为物理资源路径
return "forward:/jsp/ok.jsp";//当添加了forward前缀之后,视图解析器中的前后缀就失效了,必须自己编写绝对路径
}
//使用ModelAndView转发
@RequestMapping("test01-2")
public ModelAndView test012(){
System.out.println("test01-2-------------");
ModelAndView mv=new ModelAndView();
mv.addObject("teamName","热火");
//mv.setViewName("ok");//默认方式:由视图解析器处理之后将逻辑视图转为物理资源路径
mv.setViewName( "forward:/jsp/ok.jsp");//当添加了forward前缀之后,视图解析器中的前后缀就失效了,必须自己编写绝对路径
return mv;
}
//2、重定向到一个JSP页面
//使用字符串重定向
@RequestMapping("test02-1")
public String test021(HttpServletRequest request){
request.setAttribute("teamName","勇士");//页面上无法获取到存储在request作用域中的值,请求中断了
return "redirect:/jsp/ok.jsp";//当添加了redirect前缀之后,视图解析器中的前后缀就失效了,必须自己编写绝对路径
}
//使用ModelAndView重定向
@RequestMapping("test02-2")
public ModelAndView test022(){
ModelAndView mv=new ModelAndView();
mv.addObject("teamName","huangfeng");
mv.addObject("teamId","1002");//存储在request作用域中的值以参数的形式追加在URL后面 http://localhost:8080/jsp/ok.jsp?teamName=huangfeng&teamId=1002
mv.setViewName( "redirect:/jsp/ok.jsp");//当添加了redirect前缀之后,视图解析器中的前后缀就失效了,必须自己编写绝对路径
return mv;
}
//3、转发或者重定向到控制器
@RequestMapping("test03-1")
public ModelAndView test031(HttpServletRequest request){
System.out.println("test03-1---转发到控制器");
ModelAndView mv=new ModelAndView();
mv.addObject("teamName","达拉斯小牛");
mv.setViewName("forward:/navigation/test01-1");
return mv;
}
@RequestMapping("test03-2")
public ModelAndView test032(HttpServletRequest request){
System.out.println("test03-1---重定向到控制器");
ModelAndView mv=new ModelAndView();
mv.addObject("teamName","kaierteren");
mv.addObject("teamId","1003");
mv.setViewName("redirect:/navigation/test01-1");//参数值直接追加到URL后面
return mv;
}
它是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件,它主要用于 客户端和服务端 交互类的软件。基于这个风格设计的软件可以更简介,更有层次,更易于实现缓存等机 制。
RESTful 的核心思想就是客户端的用户发出的数据操作指令都是 " 动词 + 宾语 " 的结构。例如 GET/expresses 这个命令, GET 是动词, /expresses 是宾语。动词通常就是五种 HTTP 方法,对应 CRUD 操作。GET :读取( Read )POST :新建( Create )PUT :更新( Update )PATCH :更新( Update ),通常是部分更新DELETE :删除( Delete )
GET: 200 OK 表示一切正常POST: 201 Created 表示新的资源已经成功创建PUT: 200 OKPATCH: 200 OKDELETE: 204 No Content 表示资源已经成功删除304 : Not Modified 客户端使用缓存数据400 Bad Request :服务器不理解客户端的请求,未做任何处理。401 Unauthorized :用户未提供身份验证凭据,或者没有通过身份验证。403 Forbidden :用户通过了身份验证,但是不具有访问资源所需的权限。404 Not Found :所请求的资源不存在,或不可用。405 Method Not Allowed :用户已经通过身份验证,但是所用的 HTTP 方法不在他的权限之内。410 Gone :所请求的资源已从这个地址转移,不再可用。415 Unsupported Media Type :客户端要求的返回格式不支持。比如, API 只能返回 JSON 格式,但是客户端要求返回 XML 格式。422 Unprocessable Entity :客户端上传的附件无法处理,导致请求失败。429 Too Many Requests :客户端的请求次数超过限额。500 Internal Server Error :客户端请求有效,服务器处理时发生了意外。503 Service Unavailable :服务器无法处理请求,一般用于网站维护状态。