zoukankan      html  css  js  c++  java
  • Spring MVC 入门

    Spring Mvc概述

    Spring MVC是Spring提供的一个轻量级Web框架,它实现了 Web MVC设计模式。Spring MVC在使用和性能等方面比另外一个框架Struts2更加优异。
    Spring MVC具有如下特点。

    1. 是Spring框架的一部分,可以方便地利用Spring所提供的其它功能。
    2. 灵活性强,易于与其他框架集成
    3. 提供了一个前端控制器 DispatcherServlet,使开发人员无须额外开发控制器对象。
    4. 可自动绑定用户输入,并能正确的转换数据类型。
    5. 内置了常见的校验器,可以校验用户输入。如果校验不能通过,那么就会重定向到输
    6. 入表单。
    7. 支持国际化。可以根据用户区域显示多国语言。
    8. 支持多种视图技术。它支持JSP、Velocity和 FreeMarker等视图技术。
    9. 使用基于xML的配置文件,在编辑后,不需要重新编译应用程序。

    第一个Spring MVC应用

    1.创建项目,引入JAR包

    2.配置前端控制器

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
             xmlns=http://java.sun.com/xml/ns/javaee
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             id="WebApp_ID" version="3.0">
      <servlet>
      <!-- 配置前端过滤器 -->
          <servlet-name>springmvc</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <!-- 初始化时加载配置文件 -->
          <init-param>
               <param-name>contextConfigLocation</param-name>
               <param-value>classpath:springmvc-config.xml</param-value>
          </init-param>
       <!-- 表示容器在启动时立即加载Servlet -->
       <load-on-startup>1</load-on-startup>
       </servlet>
       <servlet-mapping>
           <servlet-name>springmvc</servlet-name>
           <url-pattern>/</url-pattern>
       </servlet-mapping>
    </web-app>
    

    在< servlet>中,配置了 Spring MVC的前端控制器 DispatcherServlet,并通过其子元素配置了Spring MVC配置文件的位置,元素中的1表示容器在启动时立即加载这个Servlet;在中,通过元素的“/”,会将所有URL拦截,并交由 DispatcherServlet处理。

    3.创建 Controller类

    ControllerTest.java:

    package com.ssm.controller;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;
    public class ControllerTest implements Controller {
    	@Override
    	public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1)
                                                                      throws Exception {
    		ModelAndView m=new ModelAndView();
    		m.addObject("msg","第一个Spring MVC程序");
    		m.setViewName("/WEB-INF/jsp/welcome.jsp");
    		return m;
    	}
    }
    

    handleRequest()是 Controller接口的实现方法, ControllerTest类会调用该方法来处理请求,并返回一个包含视图名或包含视图名和模型的 ModelAndview对象。本案例中,向模型对象中添加了一个名称为msg的字符串对象,并设置返回的视图路径为WEB-NFAp/ welcome. jsp”,这样,请求就会被转发到 welcome. jsp页面。

    4.创建 Spring MVC的配置文件,配置控制器映射信息

    springmvc-config. 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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
    <!--配置处理器Handle,映射"controllerTest"请求 -->
    <bean name="/controllerTest" class="com.ssm.controller.ControllerTest" />
    <!--处理器映射,将处理器Handle的name作为url进行查找 -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!--处理器适配器,配置对处理器中handleRequest()方法的调用 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    <!--视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
    </beans>
    

    首先定义了一个名称为“/ControllerTest”的Bean,该Bean会将控制器类ControllerTest映射到“/ControllerTest”请求中;然后配置了处理器映射器BeanNameUrlHandlerMapping和处理器适配器 SimpleControllerHandlerAdapter,其中处理器映射器用于将处理器Bean中的的name(即url)进行处理器查找,而处理器适配器用于完成对 ControllerTest处理器中handleRequest()方法的调用。最后配置了视图解析器InternalResourceViewResolver来解析结果视图,并将结果呈现给用户。

    5.创建视图(View)页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    	<title>入门程序</title>
    	</head>
    	<body>
    			${msg}
    	</body>
    </html>
    

    总结一下Spring MVC程序的执行流程

    (1)用户通过浏览器向服务器发送请求,请求会被 Spring MVC的前端控制器DispatcherServlet所拦截。
    (2)DispatcherServlet拦截到请求后,会调用 HandlerMappIng处理器映射器。
    (3)处理器映射器根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
    (4)DispatcherServlet会通过返回信息选择合适的 HandlerAdapter(处理器适配器)。
    (5)HandlerAdapter会调用并执行Handler(处理器),这里的处理器指的就是程序中编写的 Controller类,也被称之为后端控制器。
    (6)Controller执行完成后,会返回一个 ModelAndview对象,该对象中会包含视图名或包含模型和视图名。
    (7)HandlerAdapter将ModelAndView对象返回给 DispatcherServlet。
    (8)DispatcherServlet会根据ModelAndView对象选择一个合适的 ViewReslover(视图解析器)。
    (9)ViewReslover解析后,会向DispatcherServlet中返回具体的View(视图)。
    (10)DispatcherServlet对View进行渲染(即将模型数据填充至视图中)。
    (11)视图渲染结果会返回给客户端浏览器显示。

    在上述执行过程中,DispatcherServlet、HandlerMapping、HandlerAdapter和ViewResolver对象的工作是在框架内部执行的,开发人员并不需要关心这些对象内部的实现过程,只需要配置前端控制器( DispatcherServlet),完成 Controller中的业务处理,并在视图中(View)中展示相应信息即可。

    Spring MVC的注解

    DispatcherServlet

    DispatcherServlet的全名是org. springframework. web. servlet. DispatcherServlet,它在程序中充当着前端控制器的角色。在使用时,只需将其配置在项目的 web.xml文件中,其配置代码如下。

    	<servlet>
    		<!-- 配置前端过滤器 -->
    		<servlet-name>springmvc</servlet-name>
    		<servlet-class>org.srpingframework.web.servlet.DispatcherServlet</servlet-class>
    		<!-- 初始化时加载配置文件 -->
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath:springmvc-config.xml</param-value>
    		</init-param>
    		<!-- 表示容器在启动时立即加载Servlet -->
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>springmvc</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    

    如果没有通过元素配置,则应用程序会默认到WEB-NF目录下寻找如下方式命名的配置文件。
    servletName-servlet. xml
    其中,servletName指的是部署在web.xml中的DispatcherServlet的名称,在上面 web. xml中的配置代码中即为 springmvc,而-servlet. xml是配置文件名的固定写法,所以应用程序会在WEB-INF下寻找 springmvc-servlet.xml。

    Controller注解类型

    org. springframework.stereotype.Controller注解类型用于指示Spring类的实例是一个控制器,其注解形式为@Controller。该注解在使用时不需要再实现 Controller接口,只需要将@ Controller注解加入到控制器类上,然后通过 Spring的扫描机制找到标注了该注解的控制器即可。
    @Controller注解在控制器类中的使用示例如下。

    package com. ssm. controller;
    import org.springframework.stereotype.Controller;
    ……
    @Controller
    public class ControllerTest{
    ……
    }
    

    为了保证 Spring能够找到控制器类,还需要在Spring MVC的配置文件中添加相应的扫描配置信息,具体如下。
    (1)在配置文件的声明中引入spring-context。
    (2)使用<context: component-scan>元素指定需要扫描的类包。

    <?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"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    	<!--指定需要扫描的包 -->
    	<context:component-scan base-package="com.ssm.controller" />
    </beans>
    

    <context: component-scan>元素的属性base-package指定了需要扫描的类包为 com.ssm.controller。在运行时,该类包及其子包下所有标注了注解的类都会被 Spring所处理。与实现了ontroller接口的方式相比,使用注解的方式显然更加简单。同时,Controller接口的实现类只能处理一个单一的请求动作,而基于注解的控制器可以同时处理多个请求动作,在使用上更加的灵活。因此,在实际开发中通常都会使用基于注解的形式。
    注意:使用注解方式时,程序的运行需要依赖Spring的AOP包,因此需要向lib目录中添加spring.aop-4.3.6 RELEASE. Jar,否则程序运行时会报错。

    RequestMapping注解类型

    1.@ RequestMapping注解的使用

    Spring通过@Controller注解找到相应的控制器类后,还需要知道控制器内部对每一个请求是如何处理的,这就需要使用org.springframework.web.bind.annotation.RequestMapping注解类型。RequestMapping主解类型用于映射一个请求或一个方法,其注解形式为@ Request Mapping,可以使用该注解标注在一个方法或一个类上。
    (1)标注在方法上
    当标注在一个方法上时,该方法将成为一个请求处理方法,它会在程序接收到对应的URL请求时被调用。使用@ RequestMapping注解标注在方法上的示例如下。

    package com.ssm.controller;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    ……
    @Controller
    public class AnnotationControllerTest {
     	@RequestMapping(value="/annotationController")
     	public ModelAndView handleRequest(HttpServletRequest arg0, 
                                       HttpServletResponse arg1) throws Exception {
         ……
    		return m;
    	 }
    }
    

    使用@RequestMapping注解后,上述代码中的 handleRequest()方法就可以通过地址http://localhost:8080/chapter11/annotationController进行访问。

    (2)标注在类上
    当标注在一个类上时,该类中的所有方法都将映射为相对于类级别的请求,表示该控制器所处理的所有请求都被映射到vaue属性值所指定的路径下。使用@RequestMapping注解标注在类上的示例如下。

    package com.ssm.controller;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    ……
    @Controller
    @RequestMapping(value="/controll")
    public class AnnotationControllerTest {
     	@RequestMapping(value="/annotationController")
     	public ModelAndView handleRequest(HttpServletRequest arg0, 
                                       HttpServletResponse arg1) throws Exception {
         ……
    		return m;
    	 }
    }
    

    由于在类上添加了@RequestMapping注解,并且其vaue属性值为“/controll”,所以上述代码方法的请求路径将变为http://localhost:8080/chapter11/ controll /annotationController。如果该类中还包含其他方法,那么在其他方法的请求路径中也需要加入“/ controll "。

    2.@ RequestMapping注解的属性

    3.组合注解

    组合注解如下所示。

    1. @ GetMapping:匹配GET方式的请求。
    2. @ PostMapping:匹配POST方式的请求。
    3. @ PutMapping:匹配PUT方式的请求。
    4. @ DeleteMapping:匹配DELETE方式的请求。
    5. @ PatchMapping:匹配PATCH方式的请求。
      以@ GetMapping为例,该组合注解是@ RequestMapping(method= RequestMethod. GET)的缩写,它会将Http Get映射到特定的处理方法上。在实际开发中,传统的@RequestMapping
      注解使用方式如下。
    @RequestMapping(value="/user/{id}",method=RequestMethod.GET
    public String selectUserById(string id){
    ……
    }
    

    而使用新注解@GetMapping后,可以省略method属性,从而简化代码,其使用方式如下。

    @GetMapping(value="/user/{fid}")
    public String selectUserById(string id){
    ……
    }
    

    4.请求处理方法的参数类型和返回类型

    在控制器类中,每一个请求处理方法都可以有多个不同类型的参数,以及一个多种类型的返回结果。例如在入门案例中,handleRequest(方法的参数就是对应请求的 HttpServletRequest和 HttpServletResponse两种参数类型。除此之外,还可以使用其他的参数类型,例如在请求处理方法中需要访问 HttpSession对象,则可以添加 HttpSession作为参数,Spring会将对象正确地传递给方法,其使用示例如下。

    @RequestMapping(value="/annotationController ")
    public ModelAndView(httpSession session)
    {
    ……
    return m;
    }
    

    常见的返回类型是ModelAndView、String和void。其中 ModelAndView类型中可以添加Model数据,并指定视图;String类型的返回值可以跳转视图,但不能携带数据;而void类型主要在异步请求时使用,它只返回数据,而不会跳转视图。

    由于ModelAndView类型未能实现数据与视图之间的解耦,所以在开发时,方法的返回类型通常都会使用String。既然 String类型的返回值不能携带数据,那么在方法中是如何将数据带入视图页面呢?这就用到了上面所讲解的Mode参数类型,通过该参数类型,即可添加需要在视图中显示的属性。
    返回String类型方法的示例代码如下。

    @RequestMapping(value=”/ annotationController”)
    public String handleRequest(HttpServletRequest arg0, HttpServletResponse arg1,
    Model model) throws Exception {
    		model.addAttribute("msg","第一个Spring MVC程序");
    		return "/WEB-INF/jsp/welcome.jsp";
    	}
    

    在上述方法代码中,增加了一个Model类型的参数,通过该参数实例的addAttribute()方法即可添加所需数据。String类型除了可以返回上述代码中的视图页面外,还可以进行重定向与请求转发,具体方式如下。
    (1)redirect重定向
    例如,在修改用户信息操作后,将请求重定向到用户查询方法的实现代码如下

    @RequestMapping(value="/update")
    public string update(httpServletRequest request,HttpServletRespoNse response,
    Model model){
    ……
    //重定向请求路径
    return "redirect: queryUser";
    }
    

    (2)forward请求转发
    例如,用户执行修改操作时,转发到用户修改页面的实现代码如下。

    @RequestMapping(value="/toEdit")
    public string toEdit(httpServletRequest request,HttpServletRespoNse response,
    Model model){
    ……
    //请求转发
    return "forward:editUser";
    }
    

    ViewResolver(视图解析器)

    Spring MVC中的视图解析器负责解析视图,可以在配置文件中定义一个ViewResolver来配置视图解析器,其配置示例如下。

    <!-- 定义视图解析器 -->
    <bean id="viewResolver "
    class=" org.springframework.web.servlet.view.InternalResourceViewResolver ">
    <!-- 设置前缀 -->
    <property name="prefix" value="/WEB-INF/jsp/" />
    <!--设置后缀-->
    <property name="suffix" value=".isp" />
    </bean>
    

    定义了一个id为 viewResolver的视图解析器,并设置了视图的前缀和后缀属性。这样设置后,方法中所定义的view路径将可以简化。例如,入门案例中的逻辑视图名只需设置为“welcome”,而不再需要设置为“/WEB-INF/jsp/welcome.jsp",在访问时视图解析器会自动地增加前缀和后缀。

    版权声明:本文为博主原创文章,转载请附上博文链接!
  • 相关阅读:
    简历
    Servlet 三大域对象
    jsp分页
    fastadmin开发api的时候,遇到一些疑问
    RSA的基本原理,B站视频2部
    php函数注释规范
    vscode查看函数跳转定义处,和跳转引用处
    api接口发的规范和具体的细节
    restful规范是什么?为什么推荐使用restful风格,他的好处是什么?
    在线考试系统的逻辑思路
  • 原文地址:https://www.cnblogs.com/zq98/p/13195083.html
Copyright © 2011-2022 走看看