SpringMVC
SpringMVC
开始啦,这是SpringMVC框架的学习博客内容,最近高强度更新,我的学习压力也很大
首先先区分两个东西,MVC和SpringMVC
- MVC是一种设计模式,Model-View-Controller的缩写,模型-视图-控制器
 - SpringMVC是Spring框架中的一个模块,是基于MVC设计模式实现的Web框架
 
三层架构&MVC
三层架构是指将应用程序分为表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)三部分。每一层都有其特定的职责和功能。
我们这样搞简直是强迫症福音,可以将每个部分负责的功能都老老实实的分离开来,互不干扰,每个部分都有自己的职责和功能。
- 表现层:web层,用来与客户端进行数据交互,表现层一般会采用MVC的设计模型。
 - 业务层:处理具体业务逻辑的
 - 持久层:用来操作数据库
 
MVC全称Model View Controller,是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分:
Model(模型):指数据模型。用于存储数据以及处理用户请求的业务逻辑。在Web应用中,JavaBean对象,用来进行数据封装
View(视图):用于展示模型中的数据的,一般为jsp或html文件。
Controller(控制器):用来接受用户的请求。
SpringMVC
SpringMVC是一个基于MVC模式的轻量级Web框架,是Spring框架的一个模块,和Spring可以直接整合使用。
SpringMVC代替了Servlet技术,它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。
天啊是SpringMVC大人,它的出现解决了Servlet的问题,简化了开发流程,提高了开发效率。
但是我选择等待SpringBoot大人,那位大人更加强大。
SpringMVC的优点
- 基于MVC模式,结构清晰,易于维护
 - 松耦合,高内聚
 支持RESTful风格的URL
- RESTful风格表达起来是这样的:他把URL的路径部分作为资源的标识符,把HTTP方法作为对资源的操作。
1
2
3
4GET /users/123
POST /users
PUT /users/123
DELETE /users/123 
- RESTful风格表达起来是这样的:他把URL的路径部分作为资源的标识符,把HTTP方法作为对资源的操作。
 支持自定义的视图解析器
- 支持自定义的参数绑定
 - 支持自定义的异常处理
 - 支持自定义的拦截器
 - 支持自定义的类型转换器
 
SpringMVC的使用
为了和后面的Springboot做出区分展示,我们采用JSP作为视图技术,JSP相对落后很多,现已经不太是主流开发,所以这里只是提一句
提示下,后续会用到大量的注解,如果对注解用途不清楚的话建议查看这里
1). 导入SpringMVC的依赖1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53<!--spring核心依赖-->
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>5.1.6.RELEASE</version>
   </dependency>
   <!--spring整合web的依赖-->
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-web</artifactId>
     <version>5.1.6.RELEASE</version>
   </dependency>
   <!--spring整合webmvc的依赖-->
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>5.1.6.RELEASE</version>
   </dependency>
   <!--  servlet依赖 -->
   <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <version>3.1.0</version>
     <scope>provided</scope>
   </dependency>
   <!-- jsp -->
   <dependency>
     <groupId>javax.servlet.jsp</groupId>
     <artifactId>javax.servlet.jsp-api</artifactId>
     <version>2.3.1</version>
     <scope>provided</scope>
   </dependency>
2). 配置SpringMVC的DispatcherServlet1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!-- springMVC的前端控制器
       springMVC的前端控制器,本质是一个servlet,接受所有请求
       由它调用其他的组件处理用户请求,DispatcherServlet的存在降低了组件之间的耦合度
   -->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- 设置servlet拦截的请求路径
       / 表示拦截所有请求,包括静态资源
       /* 表示拦截所有请求,不包括静态资源
   -->
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
3).src/resources资源目录下创建springMVC配置文件springmvc.xml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- context:component-scan 自动组件扫描
      base-package 指定扫描的基础包,把基础包下其子包下的类所有加了注解的类,自动扫描进IOC容器
  -->
    <context:component-scan base-package="com.iweb"/>
    <!-- 视图解析器
         视图解析器的作用是,根据控制器返回的视图名,找到对应的视图对象
         视图对象的作用是,渲染模型数据,生成最终的视图
         将prefix+视图名称+后缀 确定最终要跳转的页面  例如  /sucess.jsp
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/"/>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 开启springmvc框架的注解支持 -->
    <mvc:annotation-driven/>
</beans>
4).编写hello.jsp,路径为webapp/WEB-INF/hello.jsp1
2
3
4
5
6
7
8<html>
<body>
<h2>SpringMVC hello!!!</h2>
</body>
</html>
5).编写controller类和方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.iweb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
// 用于标识控制层  使用改注解需要开启springMVC的注解扫描
public class HelloController {
    
    
    // 用于标识请求映射  表示当前方法处理的是get请求
    // value属性表示请求的路径,method属性表示请求的方法类型
    public String sayHello(){
        System.out.println("hello world"); 
        return "hello";
    }
}
RequestMapping注解
RequestMapping注解可以作用在方法或类上
● 作用在类上:第一级访问目录
● 作用在方法上:第二级访问目录
1.name属性:该映射的引用名称
2.value/path属性:含义相同,都是设置请求路径
3.method属性:用于设置请求方式,默认是GET,
4.param属性:设置请求必须包含指定的参数,才能执行
6).部署项目
将项目部署到tomcat中,启动tomcat,在浏览器中输入http://localhost:8080/hello,即可访问到hello.jsp页面
案例执行过程分析
执行流程
1.当启动tomcat服务器的时候,会创建DispatcherServlet,就会加载springmvc.xml配置文件
2.开启了注解扫描,那么HelloController对象就会被创建
3.当发送请求,请求会先到达DispatcherServlet核心控制器,根据配置的@RequestMapper注解找到执行的具体方法
4.根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
5.tomcat服务器渲染页面,做出响应
SpringMVC处理响应
SpringMVC提供了处理响应的方式有:返回字符串,请求转发,ModelAndView,Request域设置数据,返回Model,回写字符串,回写对象/集合信息,简化注解
返回字符串
SpringMVC的视图解析器将返回的字符串转换为视图(页面)
视图解析器会根据处理器返回的字符串与xml中配置的前缀和后缀进行组合,最后组合成视图的访问路径即/WEB-INF/views/view.jsp1
2
3
4
5
6
7
8
9
public class UserController {
    
    public String hello(){
        System.out.println("hello world");
        return "hello";
    }
}
请求转发
请求转发是指,服务器收到请求后,从一个资源跳转到另一个资源的过程
请求转发的过程中,浏览器地址栏的URL不会发生变化
请求转发的过程中,只能转发到当前应用的资源
请求转发的过程中,只能转发到当前应用的资源1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class UserController {
    //此处为转到的路径地址
    public String hello(){
        System.out.println("hello world");
        return "hello";
    }
    
    public String forward(){
        System.out.println("forward");
        return "forward:/user/hello";
    }
}
ModelAndView
ModelAndView是SpringMVC提供的一个类,用于封装模型数据和视图信息1
2
3
4
5
6
7
8
9
10
  public ModelAndView method3(){
      // 创建ModelAndView对象
      ModelAndView mv=new ModelAndView();
      // 设置要跳转的视图
      mv.setViewName("view");
      // 设置视图中添加的数据
      mv.addObject("title","modelAndView");
      return mv;
  }
视图中读取数据,使用EL表达式即可完成数据的读取1
2
3
4
5
6
7
8
9
10<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false"%>
<html>
<body>
<h2>view--->${title}</h2>
</body>
</html>
Request域设置数据
使用原生的HttpServletRequest
一般情况下,在springMVC中都有对servlet原生对象的方法的替换,推荐使用SpringMVC的方式替代servlet原生对象。1
2
3
4
5
6// 向方法内注入request对象,并向域对象中添加数据即可
    
    public String method4(HttpServletRequest request){
        request.setAttribute("title","request...");
        return "view";
    }
返回Model
model对象也可以在跳转页面的时候传递数据1
2
3
4
5
  public String method5(Model model){
      model.addAttribute("name","helloModel");
      return "hello";
  }
回写字符串
有时候我们不需要跳转页面,也不需要发数据,我们只是希望浏览器能够渲染数据,这时候我们可以使用HttpServetResponse向浏览器输出数据。1
2
3
4
5
6
 public void method6(HttpServletResponse response) throws  Exception{
     // 设置响应头,防止中文乱码
     response.setContentType("text/html;charset=utf-8");
     response.getWriter().write("你好,springMVC!!!");
 }
使用spring提供的注解1
2
3
4
5
6
7
8
9/**
  *  @ResponseBody的作用就是当前方法的返回值会绑定到响应体中
  *  可以应用在方法上,也可以应用在类上,使用该注册后不会在经过视图解析器
  */
 
 
 public String method7(){
     return "hello";
 }
回写对象/集合信息
在回写对象或者集合时一般都是转成JSON格式数据,生成JSON数据的工具有很多种,常见的fastJson,但是Spring默认采用的Jackjson工具完成JSON数据的响应。
首先,我们在使用@ResponseBody注解时,需要在springmvc.xml配置文件中配置jackjson的相关配置
添加依赖1
2
3
4
5
6
7
8
9
10<!-- jackson -->
   <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>2.13.3</version>
   </dependency>
springmvc.xml配置响应结果转换器1
2
3
4
5
6
7
8
9
10
11
12<!-- 配置响应结果转换器 -->
   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
       <!-- 自定义配置 -->
       <property name="messageConverters">
           <list>
               <!-- 将响应结果转换为JSON格式数据 -->
               <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
           </list>
       </property>
   </bean>
实体类编写1
2
3
4
5
6
7public class UserInfo {
    private String name;
    private int age;
    private String sex;
    // 省略get/set方法
}
控制器编写1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 
public UserInfo  method8(){
    UserInfo user=new UserInfo("张三",18,"男");
    return user;
}
public List<UserInfo> method9(){
    List<UserInfo> users=new ArrayList<UserInfo>();
    Collections.addAll(users,new UserInfo("张三",19,"男"),
            new UserInfo("李四",20,"男"),
            new UserInfo("王武",21,"男"));
    return users;
}
简化注解1
2
3
4
5
6
7
8/**
 @RestController 该注解是类级别的注解,应用之后相当于使用了
@Controller&@ResponseBody两个借助,减少@ResponseBody注解的使用次数
**/
public class HelloController {
}
SpringMVC获取请求参数
施工中……
