Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
html
查看官方文档:https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web前端
Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。java
DispatcherServlet的做用是将请求分发到不一样的处理器web
简要分析执行流程:spring
DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。浏览器
HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。spring-mvc
HandlerExecution表示具体的Handler,其主要做用是根据url查找控制器,如上url被查找控制器为:hello。安全
HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。服务器
HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。mvc
Handler让具体的Controller执行。
Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
视图解析器将解析的逻辑视图名传给DispatcherServlet。
DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
最终视图呈现给用户。
注册DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--1.注册servlet--> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--经过初始化参数指定SpringMVC配置文件的位置,进行关联--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!-- 启动顺序,数字越小,启动越早 --> <load-on-startup>1</load-on-startup> </servlet> <!--全部请求都会被springmvc拦截 --> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
/ 和 /* 的区别:
< url-pattern > / </ url-pattern > 不会匹配到.jsp, 只针对咱们编写的请求;即:.jsp 不会进入spring的 DispatcherServlet类 。
< url-pattern > /* </ url-pattern > 会匹配 *.jsp,会出现返回 jsp视图 时再次进入spring的DispatcherServlet 类,致使找不到对应的controller因此报404错。
注意web.xml版本问题,要最新版!
注册DispatcherServlet
关联SpringMVC的配置文件
启动级别为1
映射路径为 / 【不要用/*,会404】
在resource目录下添加springmvc-servlet.xml配置文件,配置的形式与Spring容器配置基本相似,为了支持基于注解的IOC,设置了自动扫描包的功能,具体配置信息以下:
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 --> <context:component-scan base-package="com.kuang.controller"/> <!-- 让Spring MVC不处理静态资源 --> <mvc:default-servlet-handler /> <!-- 支持mvc注解驱动 在spring中通常采用@RequestMapping注解来完成映射关系 要想使@RequestMapping注解生效 必须向上下文中注册DefaultAnnotationHandlerMapping 和一个AnnotationMethodHandlerAdapter实例 这两个实例分别在类级别和方法级别处理。 而annotation-driven配置帮助咱们自动完成上述两个实例的注入。 --> <mvc:annotation-driven /> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 后缀 --> <property name="suffix" value=".jsp" /> </bean> </beans>
在视图解析器中咱们把全部的视图都存放在/WEB-INF/目录下,这样能够保证视图安全,由于这个目录下的文件,客户端不能直接访问。
@Controller @RequestMapping("/HelloController") public class HelloController { //真实访问地址 : 项目名/HelloController/hello @RequestMapping("/hello") public String sayHello(Model model){ //向模型中添加属性msg与值,能够在JSP页面中取出并渲染 model.addAttribute("msg","hello,SpringMVC"); //web-inf/jsp/hello.jsp return "hello"; } }
@Controller是为了让Spring IOC容器初始化时自动扫描到;
@RequestMapping是为了映射请求路径,这里由于类与方法上都有映射因此访问时应该是/HelloController/hello;
方法中声明Model类型的参数是为了把Action中的数据带到视图中;
方法返回的结果是视图的名称hello,加上配置文件中的先后缀变成WEB-INF/jsp/hello.jsp。
在WEB-INF/ jsp目录中建立hello.jsp , 视图能够直接取出并展现从Controller带回的信息;
能够经过EL表示取出Model中存放的值,或者对象;
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>SpringMVC</title> </head> <body> ${msg} </body> </html>
实现步骤其实很是的简单:
新建一个web项目
导入相关jar包
编写web.xml , 注册DispatcherServlet
编写springmvc配置文件
接下来就是去建立对应的控制类 , controller
最后完善前端视图和controller之间的对应
测试运行调试.
使用RESTful操做资源 :
能够经过不一样的请求方式来实现不一样的效果!以下:请求地址同样,可是功能能够不一样!
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
在Spring MVC中能够使用 @PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量上。
@Controller public class RestFulController { //映射访问路径 @RequestMapping("/commit/{p1}/{p2}") public String index(@PathVariable int p1, @PathVariable int p2, Model model){ int result = p1+p2; //Spring MVC会自动实例化一个Model对象用于向视图中传值 model.addAttribute("msg", "结果:"+result); //返回视图位置 return "test"; } }
咱们来修改下对应的参数类型,再次测试
@RequestMapping("/commit/{p1}/{p2}") public String index(@PathVariable int p1, @PathVariable String p2, Model model){ String result = p1+p2; //Spring MVC会自动实例化一个Model对象用于向视图中传值 model.addAttribute("msg", "结果:"+result); //返回视图位置 return "test"; }
用于约束请求的类型,能够收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
例如:
//映射访问路径,必须是POST请求 @RequestMapping(value = "/hello",method = {RequestMethod.POST}) public String index2(Model model){ model.addAttribute("msg", "hello!"); return "test"; }
若是咱们使用浏览器地址栏进行访问默认是Get请求,会报错405:
也能够经过注解处理 HTTP 请求的方法:@GetMapping;@PostMapping;@PutMapping;@DeleteMapping;@PatchMapping,效果是同样的
@GetMapping("/add/{a}/{b}") public String test(@PathVariable int a,@PathVariable String b, Model model) { String res=a+b; model.addAttribute("msg","get结果为"+res); return "test"; } @PostMapping("/add/{a}/{b}") public String test2(@PathVariable int a,@PathVariable String b, Model model) { String res=a+b; model.addAttribute("msg","method方法结果为"+res); return "test"; }
@Controller public class ResultSpringMVC2 { @RequestMapping("/rsm2/t1") public String test1(){ //转发 return "test"; } @RequestMapping("/rsm2/t2") public String test2(){ //重定向 return "redirect:/index.jsp"; //return "redirect:hello.do"; //hello.do为另外一个请求/ } }
一、提交的域名称和处理方法的参数名一致
提交数据 : http://localhost:8080/hello?name=kuangshen
处理方法 :
@RequestMapping("/hello") public String hello(String name){ System.out.println(name); return "hello"; }
二、提交的域名称和处理方法的参数名不一致
提交数据 : http://localhost:8080/hello?username=kuangshen
处理方法 :
//@RequestParam("username") : username提交的域的名称 . @RequestMapping("/hello") public String hello(@RequestParam("username") String name){ System.out.println(name); return "hello"; }
三、提交的是一个对象
要求提交的表单域和对象的属性名一致 , 参数使用对象便可
一、实体类
public class User { private int id; private String name; private int age; //构造 //get/set //tostring() }
二、提交数据 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15
三、处理方法 :
@RequestMapping("/user") public String user(User user){ System.out.println(user); return "hello"; }
经过Model
@RequestMapping("/ct2/hello") public String hello(@RequestParam("username") String name, Model model){ //封装要显示到视图中的数据 //至关于req.setAttribute("name",name); model.addAttribute("msg",name); System.out.println(name); return "test"; }
经过ModelAndView
public class ControllerTest1 implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { //返回一个模型视图对象 ModelAndView mv = new ModelAndView(); mv.addObject("msg","ControllerTest1"); mv.setViewName("test"); return mv; } }
经过ModelMap
@RequestMapping("/hello") public String hello(@RequestParam("username") String name, ModelMap model){ //封装要显示到视图中的数据 //至关于req.setAttribute("name",name); model.addAttribute("name",name); System.out.println(name); return "hello"; }
输入中文测试,发现乱码
SpringMVC给咱们提供了一个过滤器 , 能够在web.xml中配置 .
修改了xml文件须要重启服务器!
<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>
明天任务:进行ssm框架的整合