1. 基础知识

1.作用

解决了V-C交互的问题。servlet

在传统的Java EE项目中,使用的Controller是Servlet,在绝大部分时候,用户的每个请求都需要1个Servlet进行处理,那么,在一个比较成熟的项目中,就需要创建大量的Servlet,则会引发一系列的问题:类太多不易于管理和维护;对象太多消耗内存;关于Servlet的配置代码太长也不易于管理和维护!

2.创建项目

  1. 创建简单maven并生成web.xml文件

  2. 在项目中添加tomcat运行环境

  3. 在pom.xml中添加依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <dependencies>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    </dependency>
    </dependencies>

3.核心组件

  • 分类

    组件 作用
    DispatcherServlet 接收并分发所有请求给对应控制器(前端控制器,不处理请求)
    HandlerMapping 记录和制定分发方案(记录和处理请求路径与控制器的对应关系)
    Controller 实际处理请求生成ModeAndView
    ModeAndView 处理后的数据和视图名称
    ViewResolver 通过接收到的视图名称确定响应的视图组件
  • 流程图

  • Controller注解

    注解 名称
    @Component 通用注解
    @Controller 控制类注解
    @Service 业务类注解
    @Repository 持久层类

2. MVC流程

1. DispatcherServlet\HandlerMapping

  • 作用
    1. 项目启动时就直接初始化Spring.xml文件,不需要再使用Classpathxmlapplicationcontext进行调用.
    2. 配置了默认servlet默认转发类型.do.
  1. web.xml

    contextConfigLocation可以在class的父类里找到这一属性名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--DispatcherServlet-->
    <!--初始化servlet时调用Spring.xml文件-->
    <init-param><!--HandlerMapping:基于注解的HandlerMapping-->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:Spring.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup><!--启动时创建servlet,直接初始化,不能写在前面-->
    </servlet>
    <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern><!--配置所有路径都被servlet处理,配置后的地址不能被访问>
    </servlet-mapping>
    1. 测试

      启动时自动创建Component对象

      1
      2
      3
      4
      5
      6
      @Component
      public class User {
      public User() {
      System.out.println("User()");
      }
      }

2. Controller\ModelAndView

相当于servlet,返回值是ModelAndView

  1. String.xml

    controller扫描

    1
    <context:component-scan base-package="cn.tedu.包名"></context:component-scan>
  2. java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /**
    *1. 权限:无所谓,但是,应该使用public
    *2. 方法名:自定义
    *3. 参数:暂无[可以是接收表单或AJAX数据]
    *4. 返回值:返回[数据和]视图名.
    null:自动查找与RequestMapping名相同的文件
    String:查找与文件名相同的文件
    *5.@RequestMapping:用于映射地址和控制器
    return:用于映射控制器和文件
    */
    @controller
    public class userController{
    @RequestMapping("hello.do")
    public String showHello() {
    syso("内容");
    return "hello";//modelAndView
    }
    }
  • 测试

    当访问hello.do时控制台输出”内容”;

3.ViewResolver

决定位置

  • 原理:

    • 创建一个InternalResourceViewResolver对象(之前是自己写一个类然后创建)
    • 默认根目录是webapp,引导到/前缀/return返回值.后缀(/WEB-INF/hello.jsp)
    • 抽象类不能被直接使用,因此使用的是继承VIewResolver接口的子类
  1. Spring.xml

    ​ prefix/suffix是InternalResourceViewResolver父类的属性

    1
    2
    3
    4
    5
    6
    <context:component-scan base-package="cn.tedu.spring"></context:component-scan>
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/" />//前缀
    <property name="suffix" value=".jsp" />//后缀
    </bean>
  2. 测试

    访问hello.do,根据返回值访问网页,最后结果

3. 响应处理结果

1.重定向

1
2
3
4
5
6
7
8
9
10
11
12
13
//访问handle_reg.do----login.do
//登录
@RequestMapping("login.do")
public String showLogin(){
System.out.println("login");
return "login";
}
//处理注册:重定向
@RequestMapping("handle_reg.do")
public String handleRegister(){
System.out.println("handle_reg");
return "redirect:login.do";
}

2.转发

  • 正常情况
1
2
3
4
5
6
7
8
9
10
11
12
@RequestMapping("handle_login.do")
public String handleLogin(String username,String password,ModelMap modelMap){
if(){
String message="1";
return "login";
}else{
String message="0";
return "error";
}
modelMap.addAttribute("msg",message);
return "";
}
  • ModelAndView[不推荐]
1
2
3
4
5
6
7
8
9
10
11
@RequestMapping("handle_login.do")
public ModelAndView handleLogin(String username,String password){
if(){
String message = "1";
return "login";
}else{
String message = "0";
return "herror";
}
return "";
}

3.session

  • java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @RequestMapping("reg.do")
    public String register(HttpSession session){
    Object count = session.getAttribute("count");
    if(count==null){
    count = 1;
    }else{
    count = (Integer)count+1;
    }
    session.setAttribute("count");
    }

4. @RequestMapping[设置目录]

  • 设置父目录

    1
    2
    3
    4
    5
    6
    7
    8
    @Controller
    @RequestMapping("User")//当配置进制只允许提交方式时必须用[value="User"]
    public class User{
    @RequestMapping("login.do")
    public String login(){
    return "";
    }
    }
  • 设置只允许使用某种提交方式

    使用别的提交方式会提示405错误

    1
    2
    3
    4
    5
    6
    7
    8
    @Controller
    @RequestMapping(value="User" method=RequestMethod.POST)//只允许使用POST
    public class User{
    @RequestMapping("login.do")
    public String login(){
    return "";
    }
    }
  • postMapping

    在方法上用postMapping

5. @RequestParam(参数命名)

  • 使用情况

    1. 客户端的名字跟程序的不一样时
    2. 必须添加某一个参数时
    3. 需要添加默认值时[非默认]
    • 设置别名

      1
      2
      3
      public String handleLogin(@RequestParam("uname") String username,String password){
      //当提交的表单中的名字为uname时也可以,但是必须提交否则400错误
      }
  • 设置不必须添加参数

    默认有一个隐式required=true

    1
    @RequestParam(value="uname",required=false)
  • 设置默认值

    1
    @RequestParam(value="uname",required=false,defaultValue="")

4.拦截器

  1. 详细内容

    1. 拦截器是SpringMVC的组件,用于拦截或者放行

    2. preHandle方法中定义if满足条件时返回下列

      • return=true时:拦截器放行;
    • return=flase时:拦截器拦截;剩余的两个方法执行:postHandlle()/afterCompletion()
    1. 仅能拦截Dispatcher所配置的文件

      例子:若dispatcher仅配置了*.do文件,那么.jsp文件不经过MVC,因此不能拦截;

  2. xml配置:拦截器(拦截器的url路径/拦截器规则所在类)

    • 通配符

      通配符 作用 案例
      * 代表拦截层数 /user/* 可以拦截/user/a.jsp /user/**可以拦截/user/a.jsp和/user/a/a.jsp
      ? 代表拦截文件[不常用] /user/????.jsp
    • 黑名单

      多个拦截器时,生效顺序取决于拦截器的书写顺序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <!-- 配置拦截器链 -->
      <mvc:interceptors>
      <!--拦截器-->
      <mvc:interceptor>
      <!-- 拦截路径 -->
      <mvc:mapping path="需要拦截url地址"/>
      <!-- 拦截器类-->
      <bean class="java配置的所在类"></bean>
      </mvc:interceptor>
      </mvc:interceptors>
    • 白名单+黑名单[简易]

      白名单上的路径不经过拦截器,直接进入controller

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <mvc:interceptors>
      <mvc:interceptor>
      <!-- 1:父类下的全部为黑名单 -->
      <mvc:mapping path="/user/*"/>
      <!-- 2:父类下的例外/白名单 -->
      <mvc:exclude-mapping path="/user/reg.do"/>
      <mvc:exclude-mapping path="/user/register.do"/>
      <mvc:exclude-mapping path="/user/login.do"/>
      <mvc:exclude-mapping path="/user/handle_reg.do"/>
      <mvc:exclude-mapping path="/user/handle_login.do"/>
      <!-- 3:拦截器类 -->
      <bean class="cn.tedu.spring.拦截器类名"></bean>
      </mvc:interceptor>
      </mvc:interceptors>
  3. 拦截器类:拦截器规则[,以及是否拦截]

    需要实现HandleServletInterceptor类,并重写preHandle方法

    1
    2
    3
    4
    5
    6
    7
    8
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler)throws Exception {
    if(不满足条件){
    response.sendRedirect("/web/login.html");//重定向到一个网站
    return false;//不放行:不可以访问
    }else{
    return true;//放行:可以访问
    }
    }

5.解决乱码

  • javaEE方法失效

    javaEE中是在servlet之前生效,现在是在Controller之前生效,所以会导致失败

  • web.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <filter>
    <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

6.访问静态资源

1.<mvc:resources />

spring3.0.4之后新功能,与test测试冲突

spring.xml

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

mapping:—>location,可以使用classpath

*:当前目录

**:当前目录及子目录

2.defaultServlet[推荐]

Tomcat自带功能

web.xml

1
2
3
4
<servlet-mapping>       
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>

3.<mvc:default-servlet-handler />

最后更新: 2019年11月06日 11:36

原始链接: https://airbash.cn/2019/11/02/Spring/SpringMVC/

× 请我吃糖~
打赏二维码