xiaofengzai

什么是SpringMVC

Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。

查看官方文档:https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web

 

Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。

DispatcherServlet的作用是将请求分发到不同的处理器

SpringMVC执行原理

 

 简要分析执行流程:

  1. DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。

  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。

  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。

  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。

  6. Handler让具体的Controller执行。

  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。

  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。

  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。

  12. 最终视图呈现给用户。

注解开发MVC

配置web.xml

注册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】

    添加Spring MVC配置文件

    在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

    @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>

    小结

    实现步骤其实非常的简单:

    1. 新建一个web项目

    2. 导入相关jar包

    3. 编写web.xml , 注册DispatcherServlet

    4. 编写springmvc配置文件

    5. 接下来就是去创建对应的控制类 , controller

    6. 最后完善前端视图和controller之间的对应

    7. 测试运行调试.

    RestFul 风格

    使用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

    测试使用

    @PathVariable 注解

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

    使用method属性指定请求类型

     用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如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为另一个请求/
      }
    
    }

    数据处理

    处理提交数据

    1、提交的域名称和处理方法的参数名一致

    提交数据 : http://localhost:8080/hello?name=kuangshen

    处理方法 :

    @RequestMapping("/hello")
    public String hello(String name){
       System.out.println(name);
       return "hello";
    }

    2、提交的域名称和处理方法的参数名不一致

    提交数据 : http://localhost:8080/hello?username=kuangshen

    处理方法 :

    //@RequestParam("username") : username提交的域的名称 .
    @RequestMapping("/hello")
    public String hello(@RequestParam("username") String name){
       System.out.println(name);
       return "hello";
    }

    3、提交的是一个对象

    要求提交的表单域和对象的属性名一致  , 参数使用对象即可

    1、实体类

    public class User {
       private int id;
       private String name;
       private int age;
       //构造
       //get/set
       //tostring()
    }

    2、提交数据 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

    3、处理方法 :

    @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框架的整合

     



    分类:

    技术点:

    Spring

    相关文章: