SpringMVC的简单介绍及其使用

SpringMVC

1 概念

1.1 SpringMVC是?

SpringMVC框架作用在servlet层。

Spring MVC是基于Spring的一个模块,专门做web开发,可以理解为是Servlet的升级

1.2 MVC架构

M----model(模型)

一般情况下用于封装数据

如分页模型(Pagebean)封装了分页所需要的数据

V----view(视图)

通常视图是依据模型数据创建的

C------controller(控制器)

通常用于处理业务逻辑

在这里插入图片描述

2 SpringMVC环境搭建

引入依赖

<properties>
 <spring.verion>5.0.2.RELEASE</spring.verion>
</properties>

<dependencies>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.verion}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.verion}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.verion}</version>
 </dependency>
 <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>

 </dependency>
 <dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.0</version>
 </dependency>
</dependencies>

配置springMVC.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 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">
   <!-- 配置创建 spring 容器要扫描的包 -->
   <context:component-scan base-package="com.cq"></context:component-scan>
   <!-- 配置视图解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <!--前缀 --> 
     <property name="prefix" value="/page/"></property>
       <!--后缀 --> 
       <property name="suffix" value=".jsp"></property>
   </bean>
   <!--开启 springmvc 注解支持-->
   <mvc:annotation-driven></mvc:annotation-driven>

</beans>

配置web.xml配置文件

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
 <display-name>Archetype Created Web Application</display-name>
 <servlet>
   <servlet-name>SpringMVCDispatcherServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <!-- 配置初始化参数, 用于读取 SpringMVC 的配置文件 -->
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:springmvc.xml</param-value>
   </init-param>

 </servlet>
 <servlet-mapping>
   <servlet-name>SpringMVCDispatcherServlet</servlet-name>
   <url-pattern>/</url-pattern>
 </servlet-mapping>
</web-app>

编写controller

@Controller//自动装配到spring容器中
public class HelloController {
   @RequestMapping("/demo01")
   public String sayHello(){
       System.out.println(1);
       return "success";
   }
}

物理视图: 前缀 + 逻辑视图(success) + 后缀

项目的目录结构

在这里插入图片描述

在这里插入图片描述

springMVC的执行流程

在这里插入图片描述

具体步骤
 第一步: 发起请求到前端控制器(DispatcherServlet)
 第二步: 前端控制器请求 HandlerMapping 查找 Handler (可以根据 xml 配置、 注解进
行查找)
 第三步: 处理器映射器 HandlerMapping 向前端控制器返回 Handler, HandlerMapping 会
把请求映射为 HandlerExecutionChain 对象(包含一个 Handler 处理器(页面控制器) 对
象, 多个 HandlerInterceptor 拦截器对象), 通过这种策略模式, 很容易添加新的映射策

 第四步: 前端控制器调用处理器适配器去执行 Handler
 第五步: 处理器适配器 HandlerAdapter 将会根据适配的结果去执行 Handler
 第六步: Handler 执行完成给适配器返回 ModelAndView
 第七步: 处理器适配器向前端控制器返回 ModelAndView (ModelAndView 是 springmvc
框架的一个底层对象, 包括 Model 和 view)
 第八步: 前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的
视图(jsp)), 通过这种策略很容易更换其他视图技术, 只需要更改视图解析器即可
 第九步: 视图解析器向前端控制器返回 View
 第十步: 前端控制器进行视图渲染 ( 视图渲染将模型数据(在 ModelAndView 对象中)
填充到 request 域)
 第十一步: 前端控制器向用户响应结果

springMVC组件

DispatcherServlet前端控制器

用户请求到达前端控制器,它就相当于mvc模式中的c(controller),DispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户的请求(好像一个代理),DispatcherServlet的存在降低了组件之间的耦合性

HandlerMappering处理器映射器

HandlerMappring负责根据用户请求找到Handler(处理器).springMVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等

Handler处理器

它就是我们开发中要编写的具体业务控制器。由DispatcherServlet把用户请求转发到Handler。由handler对具体的用户请求进行处理

HandlAdapter处理器适配器

通过HandlerAdapter对处理器进行执行,通过扩展适配器可以对更多类型的处理器进行执行

View Resolver视图解析器

View Resolve负责将处理结果生成的View视图。View Resolve首先根据逻辑视图名解析成物理视图名(具体的页面地址)。在生成VIew视图对象。最后对View进行渲染将处理结果通过页面展示给用户

View:视图

一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户, 需要由程序员根据业务需求开发具体的页面

3 SpringMVC中常用的注解

为了提供开发效率,springMVC提供了很多的注解

3.1 @RequestMapping

作用: 用于建立请求 URL 和处理请求方法之间的对应关系。

出现的位置:

1,可以放到方法上

2,可以放到类上

属性:

value: 用于指定请求的 URL。 它和 path 属性的作用是一样的。
method: 用于指定请求的方式。

params: 用于指定限制请求参数的条件。

@RequestMapping(value = "demo04",method = RequestMethod.GET)
public String test04(){

    return "success";

}

3.2 @RequestParam

当前台传过来的数据名称和后台的参数名称不一样时需要用到@RequestParam进行数据的绑定

当形参和前台传递的名称不一样时可以使用@RequestParam绑定
  public String test02(@RequestParam("name") String names,@RequestParam("password") String passwords){
       System.out.println(names);
       System.out.println(passwords);
       return "success";
   }

前台传的数据可以用pojo里的类来接收

controller类

@RequestMapping("/demo02")
 public String test02(User user){
       System.out.println(user);

       return "success";
   }

前端页面

<a href="${pageContext.request.contextPath}/demo02?username=李四&password=123">[传参.....]</a>

3.3 @DateTimeFormat

对数据格式进行解析

以日期格式为例,用户在前端传递来的日期数据如果后端想用Date类型的值去接收,那么会出现400,因为SpringMVC无法自动解析Date类型的数据

方法一:通过使用注解进行前端日期格式的转换

/*
    * @Author CodeArts
    * @Description 用date类型来接收前端传来的日期数据,springmvc无法解析会出现400错误,所以springmvc提供了@DateTimeFormat进行日期数据格式的解析
    * @Date 17:17 2022/6/9
    * @Param [time]
    * @return java.lang.String
    **/
   public String deleteUser(@DateTimeFormat(pattern = "yyyy-MM-dd") Date time){
       System.out.println(time);
       return "success";
  }

方法二:自定义转换器

第一步: 定义一个类, 实现 Converter 接口, 该接口有两个泛型。:第一个是当前数据的类型,第二个是要转换的目标数据类型

public class StringToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
DateFormat format = null;
try {
if(StringUtils.isEmpty(source)) {
throw new NullPointerException("请输入要转换的日期");
} f
ormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(source);
return date;
} catch (Exception e) {
throw new RuntimeException("输入日期有误");
}
}
} 

第二步: 在 springmvc.xml 配置文件中配置类型转换器。

<!-- 配置类型转换器工厂 -->
<bean id="converterService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 给工厂注入一个新的类型转换器 -->
<property name="converters">
<array>
<!-- 配置自定义类型转换器 -->
<bean class="com.qf.convert.StringToDateConverter"></bean>
</array>
</property>
</bean>
<!--开启 springmvc 注解支持-->
<mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven>

第三步: 在 annotation-driven 标签中引用配置的类型转换服务。

<!--开启 springmvc 注解支持-->
<mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven> 

3.4 @RequestBoy

获取实体的内容(实体如表单等)

/*
* @Author CodeArts
* @Description @RequestBoy:获取实体内容:form表单的内容
* @Date 17:31 2022/6/9
* @Param [body]
* @return java.lang.String
**/
   @RequestMapping("demo06")
   public String test06(@RequestBody String body){
       System.out.println(body);
       return "success";

   }

3.5 @PathVariable

用于绑定url中的占位符。{}表示占位符

controller

/*
* @Author CodeArts
* @Description @PathVaribale 使用restFul 风格传参时必须使用该注解接收
*                {}相当于占位符
* @Date 17:36 2022/6/9
* @Param [id]
* @return java.lang.String
**/
   @RequestMapping("demo07/{id}")
   public String test07(@PathVariable("id") Integer id){
       System.out.println(id);
       return "success";
   }

前端

<a href="${pageContext.request.contextPath}/demo07/100">测试</a>

3.6 RequestHeader 注解

用户获取请求头的信息

3.7 @ModelAttribute

可以修饰无返回值和有返回值的方法,表示在控制器方法之前执行

@ModelAttribute
public void test(){
   System.out.println("ModelAttribute执行");
}

请求参数出现乱码

在web.xml配置过滤器,将过滤的资源编码格式统一

<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>
 <!-- 启动过滤器 -->
 <init-param>
   <param-name>forceEncoding</param-name>
   <param-value>true</param-value>
 </init-param>
</filter>
<!-- 过滤所有请求 -->
<filter-mapping>
 <filter-name>CharacterEncodingFilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

4 控制方法的返回值

4.1 返回String

响应用户的请求

springmvc.xml的视图解析器配置

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

controller控制类

/*
* @Author CodeArts
* @Description 使用SpringMVC的视图解析器,首先返回一个逻辑视图,通过springmvc中的视图解析器进行解析
* 物理路径: 前缀 + 逻辑视图 + 后缀 ==> /pages/success.jsp
@Date 17:38 2022/6/10
* @Param []
* @return java.lang.String
**/
@RequestMapping("test01")
public String test01(){
   return "success";
}

4.2 返回值为void

使用serveltAPI进行页面跳转

1,请求转发

2,重定向

请求转发和重定向的比较

  1. 请求转发只执行了一次请求,而重定向执行了两次
  2. 请求转发地址栏不变,重定向地址栏发生变化(所以在表单数据提交时要用重定向在刷新时地址栏发生改变不会出现重复提交)
  3. 请求转发不能访问其他服务器中的资源,重定向可以
  4. 请求转发的性能要优于重定向
4.2.1 请求转发
/*
* @Author CodeArts
* @Description 使用原生的Servlet的请求转发
* @Date 17:44 2022/6/10
* @Param [request, response]
* @return void
**/
   @RequestMapping("test02")
   public void test02(HttpServletRequest request, HttpServletResponse response){
       System.out.println(username);
       try {
        request.getRequestDispatcher("/pages/success.jsp").forward(request, response);//请求转发
       } catch (Exception e) {
           e.printStackTrace();
       } 
   }
4.2.2 重定向
/*
* @Author CodeArts
* @Description 使用原生的Servlet的重回定向
* @Date 17:44 2022/6/10
* @Param [request, response]
* @return void
**/
@RequestMapping("test03")
public void test03(HttpServletRequest request, HttpServletResponse response){
   try {
       response.sendRedirect("/pages/success.jsp");//重定向
   } catch (Exception e) {
       e.printStackTrace();
   }

}

4.3 springMVC的请求转发和重定向

controller方法在提供了String类型的返回值之后,默认就是请求转发

4.3.1 转发

forward:表示转发

@RequestMapping("test08")
public String test08(){
   return "forward:/pages/success.jsp";
}
4.3.2 重定向

redirect:表示重定向

@RequestMapping("test09")
public String test09(){
   return "redirect:/pages/success.jsp";
}

4.4 返回ModelAndView

ModelAndView是springmvc中的一个可以用于传递值的对象

/*
* @Author CodeArts
* @Description springMVC提供了ModelAndView对象,其也可以进行传参
* @Date 18:30 2022/6/10
* @Param []
* @return org.springframework.web.servlet.ModelAndView
**/
@RequestMapping("test04")
public ModelAndView test04(){
   ModelAndView modelAndView = new ModelAndView();
   modelAndView.addObject("name","李四");//要携带到物理视图的数据
   modelAndView.setViewName("success");//设置逻辑视图
   return modelAndView;
}

5 springmvc作用域传值

5.1 Request域对象传值

使用原生的request共享域

@RequestMapping("test05")
 public void test05(HttpServletRequest request,HttpServletResponse response){
     request.setAttribute("name","wanger");
     try {
         request.getRequestDispatcher("/pages/success.jsp").forward(request,response);
     } catch (ServletException e) {
         e.printStackTrace();
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

扩展知识

四个域对象

1.PageContext:代表一个jsp页面,范围就是当前的jsp页面

2.Request:代表一次请求,范围就是一次请求中有效

3.Session:代表一次会话,范围就是一次会话(会话:从浏览器到开启到浏览器结束)

4.ServletContext:代表当前的web程序,只要项目在,范围就在
域对象的常用方法

setAttribute(String key,Object value)//以键值对的形式存值

getAttribute(String key)//通过键来取值

removeAttribute(String key)//清除对应键的值

5.2 Map传值

使用map集合往前台传值

@RequestMapping("test06")
   public String test06(Map<String,Object> map){
       map.put("name","cq");
       return "success";
   }

5.3 model对象传值

springMVC提供了Model对象进行传值

@RequestMapping("test07")
public String test07(Model model){
   model.addAttribute("name","cc");
   return "success";
}

5.4 ModelAndView对象传值

同 4.4

4,5方法的总的测试页面以及跳转的页面

index.jsp

<%--
 Created by IntelliJ IDEA.
 User: 86186
 Date: 2022/6/10
 Time: 17:16
 To change this template use File | Settings | File Templates.
--%>
<%--${pageContext.request.contextPath} 当前的项目名称--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/hello/test01">搭建SpringMVC环境</a>
<br>
<%--<a href="${pageContext.request.contextPath}/hello/test02">原生的servlet的请求转发跳转</a><br>--%>
<form action="${pageContext.request.contextPath}/hello/test02" method="post">
   用户名:<input type="text" name="username">
   <input type="submit" value="提交">
</form>
<a href="${pageContext.request.contextPath}/hello/test03">原生的servlet的重定向</a><br>
<a href="${pageContext.request.contextPath}/hello/test04">ModelAndView对象传参</a><br>

<hr>
<a href="${pageContext.request.contextPath}/hello/test05">requert域传值</a><br>
<a href="${pageContext.request.contextPath}/hello/test06">使用map传值</a><br>
<a href="${pageContext.request.contextPath}/hello/test07">使用model对象传值</a><br>
<a href="${pageContext.request.contextPath}/hello/test08">使用springmvc的转发</a><br>
<a href="${pageContext.request.contextPath}/hello/test09">使用springmvc的重定向</a><br>
</body>
</html>

success.jsp

<%--
 Created by IntelliJ IDEA.
 User: 86186
 Date: 2022/6/10
 Time: 17:26
 To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<h1>hello SpringMVC</h1>
<h2>${name}</h2>
</body>
</html>

6 接收响应json数据

引入解析json数据以及响应json数据的依赖

<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-databind</artifactId>
 <version>2.9.0</version>
</dependency>
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-core</artifactId>
 <version>2.9.0</version>
</dependency>
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-annotations</artifactId>
 <version>2.9.0</version>
</dependency>

controller方法

@RequestMapping("test11")
//接收前台的json数据
//将后台的pojo以json的格式传递给前台
public @ResponseBody User test11(@RequestBody User user){
   System.out.println(user);
   user.setId(2);
   user.setName("理工");
   return user;
}

注意:

@RequestBody:会自动的将前台传递的json格式的数据转换成pojo对象。
@ResponseBody:会自动的将pojo对象以json格式的数据传递给前台。

前台代码:

需要引入JQuery

<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>

<input type="button" value="测试ajax请求json和响应json" id="testJson"/>
<script>
   $(function(){
       $("#testJson").click(function () {
           $.ajax({
               type:"post",
               url:"${pageContext.request.contextPath}/hello/test11",
               contentType:"application/json;charset=UTF-8",
               data:'{"id":1,"name":"lisi"}',
               success:function (data) {
                   alert(data);

               }
           })

       })
   })
</script>

pojo实体的User类

package com.cq.pojo;

/**
* @BelongsProject: SpringMVC-demo
* @BelongsPackage: com.cq.pojo
* @Author: CodeArts
* @CreateTime: 2022-06-10  19:58
* @Description: TODO
* @Version: 1.0
*/
public class User {
   private Integer id;
   private String name;

   public User() {
   }

   public User(Integer id, String name) {
       this.id = id;
       this.name = name;
   }

   public Integer getId() {
       return id;
   }

   public void setId(Integer id) {
       this.id = id;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   @Override
   public String toString() {
       return "User{" +
               "id=" + id +
               ", name='" + name + '\'' +
               '}';
   }
}

注意:User类的属性要和json数据的key值一致

springMVC文件上传

1 引入依赖

<dependency>
 <groupId>commons-fileupload</groupId>
 <artifactId>commons-fileupload</artifactId>
 <version>1.3.1</version>
</dependency>
<dependency>
 <groupId>commons-io</groupId>
 <artifactId>commons-io</artifactId>
 <version>2.4</version>
</dependency>

2 controller处理方法

@Controller
@RequestMapping("file")
public class FileController {
   @RequestMapping("upload")
   public String upload(HttpServletRequest request, MultipartFile upload){
       //获取要上传的文件目录
       String path = "G:\\demo";
       //创建文件对象
       File file = new File(path);
       if(!file.exists()){
           //创建文件
           file.mkdir();
       }
       //获取文件上传的名称
       String fileName = upload.getOriginalFilename();
       try {
           upload.transferTo(new File(path,fileName));
       } catch (IOException e) {
           e.printStackTrace();
       }
       return "success";

   }
}

3 springmvc.xml中配置文件解析

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <property name="defaultEncoding" value="UTF-8" />
   <property name="maxUploadSize" value="2097152" />
</bean>

SpringMVC对异常的处理

1 通过配置异常处理页

在web.xml中配置异常处理也

<error-page>
 <error-code>500</error-code>
 <location>/error/500.jsp</location>
</error-page>

2 在SpringMVC中通过注解进行异常处理

@ExceptionHandler(value = {Exception.class})//Exception:表示所有的异常,可以改变比如写算数异常等
public ModelAndView Exce(Exception e){
   ModelAndView modelAndView = new ModelAndView();
   modelAndView.addObject("msg",e.toString());
   modelAndView.setViewName("error");
   return modelAndView;

}

3 通过继承异常处理接口

package com.cq.handler;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @BelongsProject: SpringMVC-demo
* @BelongsPackage: com.cq.handler
* @Author: CodeArts
* @CreateTime: 2022-06-10  21:24
* @Description: TODO
* @Version: 1.0
*/
@Component
public class MyExce implements HandlerExceptionResolver {
   @Override
 //ModelAndView传参
   public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
       ModelAndView modelAndView = new ModelAndView();
       modelAndView.addObject("msg",e.toString());
       modelAndView.setViewName("error");
       return modelAndView;
   }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值