Spring MVC学习笔记

springmvc是servlet的升级,在servlet的基础上加入一些功能,让web开发方便

springmvc能够创建对象,放入到springmvc容器中

使用@Controller注解创建的是一个普通类的对象,不是servlet对象,springmvc赋予了控制器对象一些额外的功能

web开发的底层就是servlet,springmvc中有一个对象是servlet:DispatherServlet(中央调度器)也叫前端控制器,font controller

index.jsp——DispatherServlet——转发,分配给——Controllet对象(@Controller创建的对象)

第一个springmvc项目

需求:用户在页面发起一个请求,请求交给springmvc的控制器对象,并显示请求的处理结果

实现步骤:

  1. 新建web maven

  2. 加入依赖 spring-webmvc依赖 ,jsp依赖,servlet依赖

  3. 重点:

    在web.xml中注册springmvc的核心对象DispacherServlet

    DispacherServlet是一个servlet,负责接收用户提交的请求,调用其它的控制对象,并把请求的处理结果显示给用户 ,方法返回值 void Object String ModelAndView

  4. 创建一个发起请求的index.jsp

  5. 创建控制器类

    在类上面加上注解@Controller注解,创建对象,并加入到springmvc容器中

    在类中的方法上面加入@RequestMapping注解,请求映射

  6. 创建显示结果的jsp

  7. 创建springmvc的配置文件,springmvc.xml

    声明组件扫描器,指定@Controller注解所在的包名

    声明视图解析器,帮助处理视图的

springmvc执行简单源码过程分析

  1. tomcat启动时,创建容器的过程

    • 通过load-on-start标签指定的1,在启动tomcat时创建DispacherServlet对象

    • DispacherServlet的父类是继承HttpServlet,是一个servlet,在被创建时,会执行init()方法

    • 在init()方法中,创建容器,读取配置文件

      1
      2
      3
      4
      //创建容器,读取配置文件
      WebApplicationContext ctx=new ClassPathXmlApplicationContext("springmvc.xml")
      //把容器对象放入到servletContext中
      getServletContext().setAttribute(key,value)
    • 上面创建容器的作用:创建@Controller注解所在类的对象,进而创建Controller对象,把对象放到springmvc容器中

  2. 请求处理的过程

    • 执行servlet的service方法调用doDispach方法调用Controller对象中对应的方法

接收请求的参数

  1. HttpServletRequest
  2. HttpServletResponse
  3. HttpSession
  4. 用户提交的数据
    • 逐个接收
    • 对象接收

处理器方法的返回值

  1. ModelAndView——既有数据,又有视图,对视图进行forward
  2. String——表示视图,可以是逻辑名称,也可以是完整视图路径
  3. void——不能表示数据,也不能表示视图,在处理Ajax时,可以使用void返回值,通过HttpServletResponse输出数据,响应AJax请求
  4. Object——表示数据,和视图无关,可以使用对象表示的数据,响应ajax请求

用Object返回值做JAjax,主要使用json的数据格式,实现步骤:

  1. 加入处理json的依赖,springmvc默认使用jackson

  2. 在springmvc配置文件中加入 <mvc:annotation-driven>注解驱动

    1
    2
    相当于做了
    json=om.writerValueAsString(student);
  3. 在处理器方法的上面加上@ResponseBody注解

    1
    2
    3
    相当于做了
    response.setContentType("application/json;charset=utf-8");
    response.getWriter.write(json);
  4. <mvc:annotation-driven>注解驱动原理

    完成java对象到json、xml、tetx、二进制等数据格式的转换

    HttpMessageConverter接口:消息转换器,这个接口有很多实现类,完成java对象到json、xml、tetx、二进制等数据格式的转换

  5. @ResponseBody注解:把处理器方法返回对象转换为json后,通过HttpServletResponse输出给浏览器

区分返回值String是视图还是数据,看有没有@ResponseBody注解,有的话返回的是数据,没有是视图

1
2
//设置中文乱码produces属性
@RequestMapping(value = "/string.do",produces="text/plain;chaset=utf-8")

tomcat本身能处理静态资源的访问,例如图片、HTML、js等

tomcat的web.xml文件中有一个名为default的servlet,在服务器启动时创建

作用:1.处理静态资源

​ 2.未映射到其它servlet的请求

url-parrern可以使用两种值
1.扩展名方式:**.xx,例如* *.do
2.使用斜杠 “/”

​ 当项目中使用 / ,它会替代tomcat中的default这个servlet的mapping

​ 导致所有的静态资源都给DispacherServlet处理,默认情况下 DispacherServlet是没有处理静态 资源的控制器对象的,所以访问静态资源是404

​ 动态资源可以访问,因为我们程序中定义了对应的控制器对象

url-pattern 使用 / 处理静态资源的方式:

第一种

在springmvc配置文件中加入 <mvc:default-servlet-handler>

原理是:加入这个标签后,框架会创建控制器对象DefaultServletHttpRequestHandler,类似于我们自己创建的控制器对象,这个对象把接收的请求转发给tomcat的default这个servlet

第二种

在springmvc配置文件中加入 <mvc:resources mapping="" location="">

加入后框架会创建ResourceHttpRequestHandler这个处理器对象,用这个对象处理静态资源,不依赖tomcat服务器

mapping:访问静态资源的url地址,使用通配符 **

location:静态资源在你的项目中的目录位置

直接把静态资源放在statics目录下

1
<mvc:resources mapping="/statics/**" location="/statics/"/>

路径+资源:localhost:8080/chapter06/user/index.html

路径:localhost:8080/chapter06/user/

资源:index.html

访问路径不加 / 时,

1
<form action="user/some.do" method="post">

访问路径加上 / 时,使用EL表达式 ${pageContext.request.contextPath}

1
<form action="${pageContext.request.contextPath}/user/some.do" method="post">

当在index.jsp点击后,第一次点击跳转正常localhost:8080/chapter06/user/index.html,第二次报404错误localhost:8080/chapter06/user/user/index.html

解决方法:

  1. 在跳转地址上面加上EL表达式 ${pageContext.request.contextPath},但是如果有多个跳转地址,就需要加多个
  2. 使用html的base标签,基地址,<base href="http://localhost:8080/chapter06/">

如果每个页面都要自己写base标签中的值得话,很麻烦

1
2
3
4
5
6
7
8
request.getContextPath()可以返回当前页面所在的应用的名字;
request.getScheme()可以返回当前页面使用的协议,http 或是 https;

<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/"
%>

<base href=<%=basePath%>/>

SSM整合

SSM也叫SSI(IBatis),第一个容器是Spring容器,负责管理service、dao、工具类对象的,第二个容器是SpringMVC容器,负责管理控制器对象、web开发相关对象的,我们要做的就是把使用的对象交给合适容器创建,管理。

spring容器和springmvc容器是由关系的,关系已经确定好了,springmvc容器是spring容器的子容器,类似于java中的继承,子可以访问父的内容

实现步骤:

数据库表:student(id 自增型 ,name,age)

  1. 新建maven web项目

  2. 加入依赖,spring,springmvc,mybatis三个框架的依赖,jackson依赖,mysql驱动,druid连接池,jsp,servlet依赖

  3. 写web.xml

    1. 注册DispacherServlet,目的:1,创建springmvc容器,才能创建控制器对象

      ​ 2,创建的是servlet,才能接收用户请求

    2. 注册spring的监听器:ContextLoderListener,目的:创建spring的容器对象,才能创建service,dao等对象

    3. 注册字符集过滤器,解决post请求乱码的问题

  4. 创建包,controller, service, dao ,entity

  5. 写springmvc,spring,mybatis配置文件,数据库属性配置文件

  6. 写代码,dao接口,mapper文件,service和实现类,controller,实体类

  7. 写jsp页面

SpringMVC核心技术

forward:表示转发,实现request.getRequestDispacher().forward()

redirect:表示重定向,实现reponse.sendRedirect()

请求转发是可以访问WEB-INF中的资源的,而重定向是不可以的

显式转发,扩展了默认的转发操作,不受视图解析器的控制

语法:setViewName(“forward:/WEB-INF/view/hello.jsp”);

作用和setViewName(“hello”);是一样的,如果view下面没有hello.jsp的话,用视图器这个访问不能访问到WEB-INF下面的内容,这个时候用forward就方便