Spring-MVC

SpringMVC

Web项目概述

  • Web项目:
    • 能够通过网络被浏览器访问的项目叫做web项目
  • Web项目组成部分:
    • 静态资源:
      • 指的是由html,css,js,jQuery等前端框架建设的所有内容, 所有的静态资源都是存放到webapp目录下;
    • 动态资源:
      • 指的是controller,service,dao等相关模块功能和数据库相关数据;
  • Web项目能够被浏览器访问需要将整个项目(包含动态资源和静态资源) 发布到tomcat服务器上;
  • tomcat运行web项目的流程:
    1. tomcat启动web项目流程
      1. tomcat启动时,首先加载web.xml文件
      2. 创建ServletContext对象application
        • 根据<contextParam>初始化application对象属性
      3. 创建过滤器filter对象
        • 根据<initParam>标签初始化filter对象属性
      4. 创建Servlet对象
        • 是否在启动时创建,取决于是否配置标签<load-on-startup>,如果没有配置,会在第一次请求时创建Servlet对象
        • 根据<initParam>标签初始化Servlet对象属性
    2. 处理请求流程
      1. 在浏览器发起请求,请求到达tomcat
        • 请求静态资源
          1. 将请求路径和参数封装到request对象中
          2. 根据request对象拿到请求信息,判断请求交给对应的servlet处理请求
          3. servlet拿到请求之后,会直接到webapp下获取静态资源
          4. 通过对象response响应给浏览器页面
        • 请求动态资源
          1. tomcat将请求信息封装到request对象和response对象中
          2. 将request,response对象作为参数传递给对应的servlet处理请求
          3. servlet在处理请求时会对应的调用controller,service,dao层方法处理业务并操作数据库
          4. 将处理结果通过response对象响应给浏览器页面

三层架构和MVC

三层架构

  • 我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就 是浏览器服务器。在 JavaEE 开发中,几乎全都是基于 B/S 架构的开发。那么在 B/S 架构中,系统标准的三层架构 包括:表现层、业务层、持久层。三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于三层架构设计的。
  • 三层架构中,每一层各司其职,以下介绍每层都负责哪些方面:
  • 表现层:
    • 也就是我们常说的web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求 web 层,web 需要接收 http 请求,完成 http 响应。 表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。 表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。 表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)
  • 业务层:
    • 也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web 层依赖业 务层,但是业务层不依赖 web 层。 业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的, 事务应该放到业务层来控制)
  • 持久层:
    • 也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进 行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库 中。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的。

MVC 模型

  • MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写, 是一种用于设计创建 Web 应用程序表现层的模式。MVC 中每个部分各司其职:

    • Model(模型):
      • 通常指的就是我们的数据模型。作用一般情况下用于封装数据。
    • View(视图):
      • 通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。 通常视图是依据模型数据创建的。
    • Controller(控制器):
      • 是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。
      • 它相对于前两个不是很好理解,这里举个例子:
      • 例如:
        • 我们要保存一个用户的信息,该用户信息中包含了姓名,性别,年龄等等。
        • 这时候表单输入要求年龄必须是 1~100 之间的整数。姓名和性别不能为空。并且把数据填充 到模型之中。
        • 此时除了 js 的校验之外,服务器端也应该有数据准确性的校验,那么校验就是控制器的该做 的。
        • 当校验失败后,由控制器负责把错误页面展示给使用者。
        • 如果校验成功,也是控制器负责把数据填充到模型,并且调用业务层实现完整的业务需求。

    在这里插入图片描述

SpringMVC 概述

SpringMVC 是什么

  • SpringMVC是基于MVC设计模式中,应用在控制层的框架,用于处理请求,响应数据;
  • SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 Spring FrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功 能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring 的 Spring MVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等。
  • SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成 为最优秀的 MVC 框架。
  • 它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

SpringMVC 的优势

  1. 清晰的角色划分:

    • 前端控制器(DispatcherServlet)
    • 请求到处理器映射(HandlerMapping)
    • 处理器适配器(HandlerAdapter)
    • 视图解析器(ViewResolver)
    • 处理器或页面控制器(Controller)
    • 验证器( Validator)
    • 命令对象(Command 请求参数绑定到的对象就叫命令对象)
    • 表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
  2. 分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。

  3. 由于命令对象就是一个 POJO,无需继承框架特定 API,可以使用命令对象直接作为业务对象。

  4. 和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。

  5. 可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。

  6. 可定制性,HandlerMapping、ViewResolver 等能够非常简单的定制。

  7. 功能强大的数据验证、格式化、绑定机制。

  8. 利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。

  9. 本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。

  10. 强大的 JSP 标签库,使 JSP 编写更容易。

    ………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配 置支持等等。

SpringMVC 和 Struts2 的优略分析

  • 共同点:
    • 它们都是表现层框架,都是基于 MVC 模型编写的。
    • 它们的底层都离不开原始 ServletAPI。
    • 它们处理请求的机制都是一个核心控制器。
  • 区别:
    • Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
    • Spring MVC 是基于方法设计的,而 Struts2 是基于类,Struts2 每次执行都会创建一个动作类。所 以 Spring MVC 会稍微比 Struts2 快些。
    • Spring MVC 使用更加简洁,同时还支持 JSR303, 处理 ajax 的请求更方便
      • (JSR303 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注 解加在我们 JavaBean 的属性上面,就可以在需要校验的时候进行校验了。)
    • Struts2 的 OGNL 表达式使页面的开发效率相比 Spring MVC 更高些,但执行效率并没有比 JSTL 提 升,尤其是 struts2 的表单标签,远没有 html 执行效率高。

Maven中tomcat插件使用

  • pom.xml

  • <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <!--指定编码格式-->
                    <uriEncoding>utf-8</uriEncoding>
                    <!--指定项目启动后的访问路径-->
                    <path>/</path>
                    <!--指定访问端口号-->
                    <port>8888</port>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

SpringMVC 快速入门

  • 需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。

  • 步骤

    1. 导入SpringMVC相关坐标

      •  <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.7.RELEASE}</version>
        </dependency>
        
    2. 在web.xml配置SpringMVC的核心控制器

      • <!-- 配置处理请求的springMVC提供的servlet对象 -->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 根据配置文件初始化dispatcherServlet -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        
    3. 创建视图页面

      • index.jsp

      • <html>
        <head>
        <title>$Title$</title>
        </head>
        <body>
        <a href="param/test1">helloWorld</a>
        </body>
        </html>
        
      • main.jsp

      • <html>
        <body>
            <h2>Hello SpringMVC!</h2>
        </body>
        </html>
        
    4. 创建Controller类并使用注解配置Controller类中业务方法的映射地址

      • @Controller
        @RequestMapping("param")
        public class ParamController {
            @RequestMapping("test1")
            public String test1(){
                System.out.println("我在处理请求");
                return "/main.jsp";
            }
        }
        
    5. 配置SpringMVC核心文件 spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
               xmlns:context="http://www.springframework.org/schema/context"
               xsi:schemaLocation="http://www.springframework.org/schema/beans 
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context 
        https://www.springframework.org/schema/context/spring-context.xsd">
            <!--配置扫描注解包-->
            <context:component-scan base-package="com.danny.controller"></context:component-scan>
            <!--创建handlerMapping实例-->
            <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
            <!--创建handlerAdapter处理器适配器实例-->
            <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
            <!--创建ViewResolver视图解析器实例-->
            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
        </beans>
        
    6. 将处理结果返回给springMVC中的DispatcherServlet,响应给浏览器页面

SpringMVC的组件解析

SpringMVC的执行流程

在这里插入图片描述

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  4. DispatcherServlet调用HandlerAdapter处理器适配器。
  5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
  6. Controller执行完成返回ModelAndView。
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
  9. ViewReslover解析后返回具体View。
  10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。

SpringMVC组件解析

  1. 前端控制器:DispatcherServlet

    • 用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
  2. 处理器映射器:HandlerMapping

    • HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
  3. 处理器适配器:HandlerAdapter

    • 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
  4. 处理器:Handler

    • 它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
  5. 视图解析器:View Resolver

    • View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
  6. 视图:View

    • SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。
    • 最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

SpringMVC的XML配置解析

  • SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件中配置了默认的视图解析器,如下:

  • org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
    
  • 翻看该解析器源码,可以看到该解析器的默认设置,如下:

  • REDIRECT_URL_PREFIX = "redirect:"  --重定向前缀
    FORWARD_URL_PREFIX = "forward:"    --转发前缀(默认值)
    prefix = "";     --视图名称前缀
    suffix = "";     --视图名称后缀
    
  • 视图解析器

  • 我们可以通过属性注入的方式修改视图的的前后缀

  • <!--配置内部资源视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    

SpringMVC的参数类型

SpringMVC的参数类型绑定

普通类型参数绑定
  • 保证传入参数名称和绑定参数名称一致:

  • @RequestMapping("test2")
    public String test2(String pname,int age){
        System.out.println("姓名:"+pname);
        System.out.println("年龄:"+age);
        return "main";
    }
    
对象类型参数绑定
  • 保证传入参数名称和对象属性名称一致:

  • @RequestMapping("test3")
    public String test3(Person person){
        System.out.println(person);
        return "main";
    }
    
复杂类型参数绑定
  • 传参方式

    • List

      • list[0], list[1], …
    • Set

      • set[0], set[1], …

      • 注意如需使用set集合必须在bean中初始化

      • 示例

        • public Person(){
              carSet=new HashSet<>();
              Car car = new Car();
              carSet.add(car);
          }
          
    • Map

      • map[‘x’], map[‘y’], …
  • @RequestMapping("test4")
    public String test4(Person person){
        System.out.println(person);
        return "main";
    }
    
默认类型参数绑定
  1. servletAPI默认参数绑定
  • @RequestMapping("test5")
    public void test5(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("我在请求转发");
        request.getRequestDispatcher("/main.jsp").forward(request,response);
    }
    
  1. ModelAndView,ModelMap,Model,Map这些类型,springMVC都可以自动绑定
  • @RequestMapping("test6")
    public ModelAndView test6(ModelAndView modelAndView, ModelMap modelMap, Model model, Map map){
        modelAndView.addObject("aa","11");
        modelMap.addAttribute("bb","22");
        model.addAttribute("cc","33");
        map.put("dd","44");
        modelAndView.setViewName("main");
        return modelAndView;
    }
    
自定义类型参数绑定
  • 自定义日期转换工具类:

  • public class MyDateConverter implements Converter<String, Date> {
        @Override
        public Date convert(String source) {
            Date date = null;
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
            try {
              date=  simpleDateFormat.parse(source);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
  • 注册日期转换工具类:(springmvc.xml中)

  • <!--注册自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.danny.util.MyDateConverter"></bean>
            </set>
        </property>
    </bean>
    <!--默认会创建多种处理器映射器和处理器适配器,和注解解析对象实例-->
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
    
  • 日期转换测试:

    • controller中
  • @RequestMapping("test7")
    public String test7(Date date){
        System.out.println(date);
        return "main";
    }
    
    • 视图页面中
  • <form method="post" action="param/test7">
    入职日期:<input name="date" type="date"/>
    <input type="submit" value="提交">
    </form>
    

SpringMVC返回参数类型

返回void参数类型
  • 只有一种情况,当使用默认的servletAPI处理请求响应数据时使用:

  • @RequestMapping("test5")
    public void test5(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("我在请求转发");
    	request.getRequestDispatcher("/main.jsp").forward(request,response);
    }
    
返回String数据类型
  1. 将返回字符串看作视图名称处理:

    • @RequestMapping("test1")
      public String test1(){
          System.out.println("我在处理请求");
          return "main";
      }
      
  2. String类型实现请求转发:

    • 必须返回字符串"forward:请求转发路径"

    • @RequestMapping("test8")
      public String test8(){
          System.out.println("我在请求转发");
          return "forward:/param/test6";
      }
      
  3. String类型实现重定向:

    • 必须返回字符串"redirect:请求路径"

    • @RequestMapping("test9")
      public String test9(){
          System.out.println("我在重定向");
          return "redirect:/param/test6";
      }
      
  4. springMVC中重定向携带参数:

    • 提供一个专门传递重定向参数的对象:RedirectAttributes

    • @RequestMapping("test9")
      public String test9(String pname, RedirectAttributes redirectAttributes){
          System.out.println("我在重定向"+pname);
          //将要重定向的参数传递到redirectAttributes中
          //redirectAttributes.addAttribute("pname",pname);
          //如果需要将重定向携带的参数隐藏,需要使用addFlushAttribute()方法添加参数
          //这种传参方式,获取重定向参数时,需要加上注解@ModelAttribute
          redirectAttributes.addFlashAttribute("pname",pname);
          return "redirect:/param/test6";
      }
      
返回ModelAndView数据类型
  • 将请求参数绑定到请求域,并指定返回视图名称:

  • @RequestMapping("test6")
    public ModelAndView test6(ModelAndView modelAndView, ModelMap modelMap, Model model, Map map,@ModelAttribute("pname") String pname){
        System.out.println(pname);
        modelAndView.addObject("aa","11");
        modelMap.addAttribute("bb","22");
        model.addAttribute("cc","33");
        map.put("dd","44");
        modelAndView.setViewName("main");
        return modelAndView;
    }
    
返回任意对象类型
  1. 引入jason转化jar包:

    • <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.9</version>
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.9.9</version>
      </dependency>
      
  2. 在控制层方法上加注解@ResponseBody

    • @ResponseBody
      @RequestMapping("test10")
      public Person test10(){
          Person person = new Person();
          person.setPname("张三");
          person.setAge(12);
          Car car = new Car();
          car.setCname("三轮车");
          car.setCprice(10);
          person.setCar(car);
          String[] hobbies={"唱歌","跳舞"};
          person.setHobbies(hobbies);
          return person;
      }
      

SpringMVC的进阶

静态资源处理

  1. 将静态资源请求交给默认的tomcat中的defaultServlet来处理(推荐)

    • <!-- 将静态资源交给默认servlet处理 -->
      <mvc:default-servlet-handler/>
      
  2. 直接指定静态资源访问路径:

    • <!-- 指定静态资源访问路径, /html/**表示以/html开头所有内容 -->
      <mvc:resources mapping="/html/**" location="/html/"/>
      

/与/*的区别

  • /*表示匹配所有的请求
  • /表示匹配除了jsp与jspx以外的所有请求 (除了能匹配的请求以外的其他请求)

SpringMVC的常用注解

  • @RequestMapping

    • 作用:
      • 用于建立请求 URL 和处理请求方法之间的对应关系 (在控制层定义请求路径的映射路径)
    • 位置:
      • 类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
      • 方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径
    • 属性:
      • value:
        • 用于指定请求的URL。它和path属性的作用是一样的
      • method:
        • 用于指定请求的方式
      • params:
        • 用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样
  • @RequestParam

    • 作用:
      • 用于设置请求参数(定义请求携带参数名称)
    • 位置:
      • 方法上
    • 属性:
      • value:
        • 用于指定要绑定的传入参数名称
      • defaultValue:
        • 用于指定当页面没有传值时的默认参数值
      • required:
        • 用于表示请求时必须传入参数, 默认是true
  • @RequestHeader

    • 作用:
      • 用于获取请求头信息
    • 位置:
      • 方法的参数上
  • @RequestBody

    • 作用:
      • 可以将请求参数json,转换成任意对象
  • @CookieValue

    • 作用:
      • 用于用户获取cookie中的参数
    • 位置:
      • 方法的参数上
  • @SessionAttributes

    • 作用:
      • 用于将请求域的参数存放到Session域中,注解在类位置上
    • 位置:
      • 类上
  • @ModelAttribute

    • 作用:
      • 用于定义公共方法并能让其他方法使用该公共方法返回的公共参数
    • 位置:
      • 方法上:
        • 表示该方法为公共方法,指定是所有请求方法执行前都会执行该方法
      • 参数前:
        • 表示获取重定向携带的参数以及公共方法返回的参数
      • 注意:
        • 要获取公共方法返回值的参数,需要在注解@ModelAttribute上定义参数名,再在需要获取参数的地方,通过注解@ModelAttribute获取参数值
  • @PathVariable

    • 作用:

      • 用于获取路径变量值, 这个注解通常使用在restful风格编码中
    • restful:

      • Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。
      • Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
        • GET:用于获取资源
        • POST:用于新建资源
        • PUT:用于更新资源
        • DELETE:用于删除资源
    • 示例:

      • 原始编程方式实现增删改查
      1. 构建用户交互页面

        restful风格编码
        新增
        <form action="/annotation/person" method="post">
            姓名<input type="text" name="name"/>
            年龄<input type="text" name="age"/>
            <input type="submit" value="新增"/>
        </form><br>
        修改
        <form action="/annotation/person" method="post">
            <input type="hidden" name="_method" value="put">
            姓名<input type="text" name="name"/>
            年龄<input type="text" name="age"/>
            <input type="submit" value="修改"/>
        </form><br>
        删除
        <form action="/annotation/person" method="post">
            <input type="hidden" name="_method" value="delete">
            需要删除的姓名<input type="text" name="name"/>
            <input type="submit" value="删除"/>
        </form><br>
        查询
        <form action="/annotation/person" method="get">
            需要查询的姓名<input type="text" name="name"/>
            <input type="submit" value="查询"/>
        </form><br>
        
      2. 定义控制层方法

        @RequestMapping(value = "person",method = RequestMethod.POST)
        public String addPerson1(Person person){
            System.out.println("我在新增用户");
            System.out.println(person);
            return "main";
        }
        @RequestMapping(value = "person",method = RequestMethod.PUT)
        public String updatePerson1(Person person){
            System.out.println("我在修改用户: ");
            System.out.println(person);
            return "main";
        }
        
        @RequestMapping(value = "person",method = RequestMethod.DELETE)
        public String deletePerson1(String name){
            System.out.println("我在删除用户: ");
            System.out.println(name);
            return "main";
        }
        @RequestMapping(value = "person",method = RequestMethod.GET)
        public String findPerson1(String name){
            System.out.println("我在查询用户: ");
            System.out.println(name);
            return "main";
        }
        
  • @ResponseBody

    • 作用:
      • 将任意对象转化为json格式字符串
    • 位置:
      • 方法上

文件上传

  • 步骤
    1. 引入文件上传jar包

      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.4</version>
      </dependency>
      
    2. 构建页面定义文件上传入口

      <html>
      <head>
          <title>Title</title>
      </head>
      <body>
      <form action="file/uploadFile" enctype="multipart/form-data" method="post">
          <input type="file" name="file">
          <input type="submit" value="upload">
      </form>
      </body>
      </html>
      
    3. 在控制层处理文件上传

      @Controller
      @RequestMapping("file")
      public class FileController {
      
          @RequestMapping("uploadFile")
          public String uploadFile(MultipartFile file){
              //获取上传文件的名称
              String filename = file.getOriginalFilename();
              File file1 = new File("C:\\Users\\u\\Desktop\\"+filename);
              //文件上传
              try {
                  file.transferTo(file1);
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return "main";
          }
      }
      
    4. 在配置文件中初始化文件上传对象

      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
      

多文件上传

  • 步骤

    1. 引入文件上传jar包

      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.4</version>
      </dependency>
      
    2. 构建页面定义文件上传入口

      <form action="file/batchUploadFile" enctype="multipart/form-data" method="post">
          <input type="file" name="files">
          <input type="file" name="files">
          <input type="submit" value="upload">
      </form>
      
    3. 在控制层处理文件上传

      @RequestMapping("batchUploadFile")
      public String batchUploadFile(@RequestParam("files") MultipartFile[] files){
          if (files != null && files.length>0){
              for (MultipartFile file : files){
                  String filename = file.getOriginalFilename();
                  File newPath = new File("C:\\Users\\u\\Desktop\\"+filename);
                  try {
                      file.transferTo(newPath);
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
          return "main";
      }
      
    4. 在配置文件中初始化文件上传对象

      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
      

文件下载

  • 步骤

    1. 定义文件下载入口

      <a href="/file/downloadFile?filePath=C:\Users\u\Pictures\Camera Roll\lbxx.jpg&fileName=springmvc.jpg">download</a>
      
    2. 处理文件下载

      @RequestMapping("downloadFile")
      public ResponseEntity<byte[]> downloadFile(String filePath, String fileName) throws IOException {
          File file = new File(filePath);
          HttpHeaders httpHeaders = new HttpHeaders();
          httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
          //以下载方式打开
          httpHeaders.setContentDispositionFormData("attachment",fileName);
          return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),httpHeaders, HttpStatus.OK);
      }
      
    3. 创建文件上传对象

      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
      

异常处理器

  • springMVC提供了异常处理器接口HandlerExceptionResolver,如果要对异常做自定义处理可以通过该接口实现;

  • 步骤

    1. 自定义异常处理类

      public class MyExceptionResolver implements HandlerExceptionResolver {
      
          @Override
          public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
              System.out.println("我在处理异常");
              ex.printStackTrace();
              ModelAndView modelAndView = new ModelAndView();
              modelAndView.setViewName("error");
              return modelAndView;
          }
      }
      
    2. 注册异常处理器实例

      <bean class="com.danny.util.MyExceptionResolver"/>
      

拦截器

  • 拦截器是属于springMVC的,依赖于springMVC框架,通过代理模式来实现,重写目标方法接口,新增额外的功能;

  • 在springMVC处理请求响应数据时,新增额外的功能;

  • 登录校验案例步骤

    1. 构建登录页面

      <html>
      <head>
          <title>Title</title>
      </head>
      <body>
      <form method="post" action="/file/login">
          账户:<input type="text" name="name"/>
          密码:<input type="password" name="password"/>
          <input type="submit" value="登录"/>
      </form>
      </body>
      </html>
      
    2. 自定义拦截器工具类重写

      public class MyInterceptor implements HandlerInterceptor {
          /**
           * 控制层请求前拦截器
           * @param request
           * @param response
           * @param handler
           * @return
           *          该方法返回true表示请求继续向下执行,由控制层处理
           *          该方法返回false表示请求中断,不会再执行控制方法
           * @throws Exception
           */
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                  throws Exception {
              //System.out.println("我是加在请求前的额外功能");
              //校验当前用户是否登录
              HttpSession httpSession = request.getSession();
              String loginSuccess = (String) httpSession.getAttribute("loginSuccess");
              if ("success".equals(loginSuccess)){
                  return true;
              }
              else {
                  //为登录跳转登录页面
                  request.getRequestDispatcher("/login.jsp").forward(request,response);
                  return false;
              }
          }
          /**
           * 控制层方法返回拦截器
           * @param request
           * @param response
           * @param handler
           * @param modelAndView
           * @throws Exception
           */
          @Override
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                                 @Nullable ModelAndView modelAndView) throws Exception {
              System.out.println("我是加在控制层方法返回的额外功能");
          }
          /**
           * 控制层方法结束后的拦截器
           * @param request
           * @param response
           * @param handler
           * @param ex
           * @throws Exception
           */
          @Override
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                      @Nullable Exception ex) throws Exception {
              System.out.println("我是加在控制层方法结束后的额外功能");
          }
      }
      
    3. 控制层处理

      @RequestMapping("login")
      public String login(String name, String password, HttpSession httpSession){
          System.out.println("登录校验成功");
          httpSession.setAttribute("loginSuccess","success");
          return "main";
      }
      
    4. 注册拦截器

      • 多个拦截器注册时,拦截器方法执行顺序就是注册拦截器的顺序
      <mvc:interceptors>
          <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <mvc:exclude-mapping path="/file/login"/>
              <bean class="com.danny.util.MyInterceptor"/>
          </mvc:interceptor>
      </mvc:interceptors>
      

过滤器

  • 过滤器是由tomcat提供的,过滤器依赖于tomcat, tomcat处理每一个请求之前都会调用过滤器处理请求,请求处理完之后会继续回到过滤器方法中;

  • 自定义过滤器实现tomcat过滤器接口filter

  • 步骤

    1. 创建自定义过滤器工具类

      public class MyFilter implements Filter {
          /**
           * 初始化filter实例时调用方法
           * @param filterConfig
           * @throws ServletException
           */
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
              System.out.println("初始化filter实例相关操作");
          }
      
          /**
           * 每次请求到达tomcat,tomcat都会根据映射调用都Filter()方法处理请求
           * @param request
           * @param response
           * @param chain
           * @throws IOException
           * @throws ServletException
           */
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              System.out.println("我是servlet请求前的过滤器处理");
              //该方法表示是否将请求交给servlet处理
              chain.doFilter(request,response);
              System.out.println("我是servlet请求后的过滤器处理");
          }
      
          /**
           *filter对象销毁时调用的方法
           */
          @Override
          public void destroy() {
              System.out.println("我是过滤器对象销毁时的处理方法");
          }
      }
      
    2. web.xml中配置自定义过滤器

      <!-- 配置自定义过滤器 -->
      <filter>
          <filter-name>myFilter</filter-name>
          <filter-class>com.danny.util.MyFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>myFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
      
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值