zoukankan      html  css  js  c++  java
  • 1.2(Spring MVC学习笔记) Spring MVC核心类及注解

    一、DispatcherServlet

      DispatcherServlet在程序中充当着前端控制器的作用,使用时只需在web.xml下配置即可。

      配置格式如下:

    <?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_3_1.xsd"
      version="3.1"
      metadata-complete="true">
      <display-name>SpringMVC</display-name>
      
      <!-- 配置前端控制器 -->
      <servlet>
          <servlet-name>springmvc</servlet-name>
          <servlet-class >
              org.springframework.web.servlet.DispatcherServlet
          </servlet-class> 
          <!-- 初始化时加载配置文件,该配置文件是在src目录下创建的。 -->
          <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>

    其中<init-param>和<load-on-startup>是可选项.

    如果<init-param>配置了xml文件的路径,则容器加载时会去指定路径加载文件。

    如果没有配置则会在WEB-INF目录下选择命名格式为servletName-servlet.xml的文件。

    servletName是我们配置的前端控制器的<servlet-name>,本例为springmvc,则会寻找springmvc-servlet.xml。

    <load-on-startup>配置为1,代表当前Servlet在容器启动时加载。

    如果没有配置,则在请求该Servelt时才对其进行加载。

    二、Controller注解

      在控制类可以通过实现Controller接口,也可以通过注解来实现。

      通过注解实现只需要在控制类上添加@Controller注解即可。

      添加注解后再xml中可通过扫描语句进行扫描。

      扫描语句:<context:component-scan base-package = "指定包" />

      

    三、RequestMapping注解

      3.1Spring通过@Controller注解找到控制器类后,还需将请求映射到具体的处理程序。

      RequesMapping注解就是用于映射请求。

      例如:

    public class FirstController{
        @RequestMapping(value = "/firstController")
        public String handleRequest(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
            // TODO Auto-generated method stub
            model.addAttribute("msg", "hello SpringMVC");
            return "first";
        }
    }

    上例中间/firstController这个请求映射到handleRequest方法。

    在浏览器地址栏输入localhost:8080/SpringMVC/firstController就可以了调用handleRequest方法。

      @RequestMapping注解也可以映射到类上。

    @RequestMapping(value = "/hello")
    public class FirstController{
        @RequestMapping(value = "/firstController")
        public String handleRequest(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
            // TODO Auto-generated method stub
            model.addAttribute("msg", "hello SpringMVC");
            return "first";
        }
    }

      映射在类上时,要想访问类中的方法必须加上类的映射请求路径。

      例如想访问handleRequest方法,完整路径为:localhost:8080/SpringMVC/hello/firstController

      

      value属性除了上述直接表示一个固定路径外,还有以下写法:

      

      3.2指定变量和值  {变量}

      例如

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping(value = "/hello")
    public class FirstController{
        @RequestMapping(value = "/firstController/{id}")//指定变量
        public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
            // TODO Auto-generated method stub
            
            System.out.println("into mv");
            System.out.println(id);
            model.addAttribute("msg", "hello SpringMVC");
            return "first";
        }
    }

    在地址栏输入loaclhost:8080/SpringMVC/hello/firsstController/xx,才能访问指定路径所映射的方法。

    而xxx可以被@pathVariable String id 中的id获取,形参名xx和路径{xx}中的名称要一致。如果没有/xxx则出现404页面。

      3.3指定变量和正则表达式 ({变量:正则表达式})

      例如将RequestMapping改为:@RequestMapping(value = "/firstController/{id:\d}")

      \代表,正则d中d代表0-9任意一个数字,这样配置后:

      /firstController/0-9任意一个数字可以访问成功(注意是一个数字,多个不符合条件),且可以通过@pathVariable获取id的值。

      /firstController/0-9之外的字符或多个数字(大于1个),访问失败,出现404页面。

      

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping(value = "/hello")
    public class FirstController{
            //末尾加上任意一位数字访问成功,反正失败
        @RequestMapping(value = "/firstController/{id:\d}")
        public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("into mv");
            System.out.println(id);
            model.addAttribute("msg", "hello SpringMVC");
            return "first";
        }
    }    

    访问失败:

     访问成功:

       RequestMapping中还有一个属性method,用于指定处理何种类型的请求方法。

      例如@RequestMapping(value = "/firstController/{id:\d}" ,method = RequestMethod.POST)处理POST类型的请求

        @RequestMapping(value = "/firstController/{id:\d}" ,method = RequestMethod.GET)处理GET类型的请求

      我们来看一个例子

    @Controller
    @RequestMapping(value = "/hello")
    public class FirstController{
        @RequestMapping(value = "/firstController/{id:\d}" ,method = RequestMethod.POST)//处理POST类型请求
        public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("into mv");
            System.out.println(id);
            model.addAttribute("msg", "hello SpringMVC");
            return "first";
        }
    }

      我们将方法设置为处理POST类型请求,使用GET类型的请求去访问会出现不支持GET类型的请求方法。

      method可以设置多个值,中间用“,”隔开@RquestMapping(method = {xxx.GET,xx.xPOST})

      Spring4.3中又引入了组合注解,例如上例中的@RequestMapping(method = Request.GET)可以简化为:

      GetMapping(),从字面上可以看出这个注解是包含了GET和Mapping。处理Get类型的请求映射。

      除此之外,还有一些组合注解:

      PostMapping,PutMapping,DeleteMapping,PatcherMapping.

      

      params属性:指定请求中必须包含、不包含某些参数、或者指定某些参数名和值要对应,才能被当前方法处理。

      例如params = {"name"} 代表请求中要包含name参数。例如:localhost:8080/SpringMVC/hello/firstController/1?name=hcf;

      这样的就可以正确访问指定的方法,反之不行。

      params={“!name”}代表请求中不包含name参数可以正确访问,反正不行。

      params={"name = hcf"},代表请求参数name要和指定的值匹配才可以正常访问,反正不行。例如

      localhost:8080/SpringMVC/hello/firstController/1?name=hcf;可以访问,

      localhost:8080/SpringMVC/hello/firstController/1?name=h;就不能访问。

      

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    @Controller
    @RequestMapping(value = "/hello")
    public class FirstController{//请求参数name为“hcf”才能访问
        @RequestMapping(value = "/firstController/{id:\d}" ,method = {RequestMethod.POST,RequestMethod.GET},params = {"name=hcf"})
        public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("into mv");
            System.out.println(id);
            model.addAttribute("msg", "hello SpringMVC");
            return "first";
        }
    }

    访问成功:

    访问失败:

    四、请求处理方法类型和返回值。

      支持的请求参数类型

      Request or response objects (Servlet API).

      Session object (Servlet API)

      org.springframework.web.context.request.WebRequest or org.springframework.web.context.request.NativeWebRequest

      java.util.Locale

      java.util.TimeZone (Java 6+) / java.time.ZoneId (on Java 8) 

       java.io.InputStream / java.io.Reader

      java.io.OutputStream / java.io.Writer

       org.springframework.http.HttpMethod

      java.security.Principal

      @PathVariable

      @RequestParam

      @RequestHeader

      @RequestBody

      @RequestPart

      @SessionAttribute

      @RequestAttribute

      HttpEntity<?>

      java.util.Map / org.springframework.ui.Model / org.springframework.ui.ModelMap

      org.springframework.web.servlet.mvc.support.RedirectAttributes

      org.springframework.validation.Errors / org.springframework.validation.BindingResult

      org.springframework.web.bind.support.SessionStatus

      org.springframework.web.util.UriComponentsBuilder

      这些是方法参数支持的类型,

      例如上例中的:

      public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exce

        参数类型都是受支持的参数类型。

      支持的返回类型:

      

         上例子中的返回值为“first”,返回字符串被解释为逻辑视图名。

      (返回first对应为/WEB-INF/jsp/first.jsp,这是因为在视图解析器中设置了前缀和后缀,后续会有具体使用方法)

    五、视图解析器(ViewResolver)

      视图解析器将DispatcherServlet中的view参数传递给视图解析器,视图解析器将解析的视图传递给DispatcherServlet。

      在视图解析中,可以设置前缀和后缀。

      例如我们设置前缀为“/WEB-INF/jsp/”,后缀设置为“.jsp”。

      以前面的Controller类为例,Controller执行完后将“first”返回给HandlerAdapter,然后返回DispathcerServlet。

      DispatcherServlet将“first”交给视图解析器,视图解析器将“first”添加前缀和后缀,变成“/WEB-INF/jsp/first.jsp”.

      然后解析指定路径视图将视图返回给DispatcherServlet。

      我们来看下前缀与后缀的具体设置:

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

    最后结合上述,使用注解实现SpringMVC

    web.xml

    <?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_3_1.xsd"
      version="3.1"
      metadata-complete="true">
      <display-name>SpringMVC</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      
      <!-- 配置前端控制器 -->
      <servlet>
          <servlet-name>springmvc</servlet-name>
          <servlet-class >
              org.springframework.web.servlet.DispatcherServlet
          </servlet-class> 
          
          <!-- 初始化时加载配置文件,该配置文件是在src目录下创建的。 -->
          <!-- <init-param>  该选项不配做会自动寻找WEB-INF下名为springmvc-servlet.xml的文件。--> 
          <!--    <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>

    Controller类

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    @Controller
    @RequestMapping(value = "/hello")
    public class FirstController{
        @RequestMapping(value = "/firstController/{id:\d}" ,method = {RequestMethod.POST,RequestMethod.GET},params = {"name=hcf"})
        public String handleRequest(String name ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("into mv");
            name = request.getParameter("name");
            System.out.println(name);
            //返回类型为String会被解释为逻辑视图名View就解决了。
            //Model交由Model对象来完成。
            model.addAttribute("msg", "hello  SpringMVC");
            return "first";
        }
    }

    springmvc-servlet.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"  
            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.springmvc.firstmvc"></context:component-scan>    
           <!-- 配置处理器(Handle),映射/firstController请求 (Controller类),已由注解完成-->
           <!-- <bean name = "/firstController" class = "com.springmvc.firstmvc.FirstController"/> -->
           <!-- 配置映射处理器(handlerMapping) 将处理器(Handle)的name作为url进行查找(Spirng4.0以后无需配置) -->
           <!-- 配置适配处理器(HandlerAdapter) 适配处理器会调用处理器(Handle)即FirstController类(Spirng4.0以后无需配置) -->
           <!-- 处理器会返回一个ModelAndView,适配处理器将返回的ModelAndView交给前端控制器去处理了 -->
           <!-- 前端控制器根据ModelAndView中的View选择一个视图解析器(ViewReslover) -->
           <!-- 前端控制器将Model(msg "hello SpringMVC")填充进视图解析器返回的视图,用户看到最后页面 -->
           <!-- 设置视图处理器及其前缀后缀 -->
           <bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
               <property name="prefix" value = "/WEB-INF/jsp/"></property>
               <property name="suffix" value = ".jsp"></property>
           </bean>
           <!-- 视图处理器解析后会将视图传递给前端控制器,前端控制对View进行渲染(将模型数据填入视图) -->
           <!-- 渲染结果会返回客户端浏览器显示 -->
    </beans>

    WEB-INF/jsp/first.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        ${msg}
    </body>
    </html>

     

    可以看到加载的是springmvc-servlet.xml

     如果firstController/后面不是一位数字,或者name不等于hcf都会出现404页面。

    完整结构:

     

    参考资料:

    SpringFramework/spring-framework-4.3.6.RELEASE/docs/spring-framework-reference/html/mvc.html

    https://www.cnblogs.com/qq78292959/p/3760560.html 

  • 相关阅读:
    c#参数传递几点小结
    c#线程初探(二)
    c#线程初探(一)
    c#:浅克隆和深克隆,序列化和反序列化
    c#冒泡、快速、选择和插入排序算法的项目应用
    c#运算符几点小结
    文件操作(无代码)
    不仅仅C#缺点(永远未完)
    《道德经》程序员版第五章
    《道德经》程序员版第四章
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/10398369.html
Copyright © 2011-2022 走看看