欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

SSM第七讲 SpringMVC概述和基础知识详解

SpringMVC概述和基础知识详解


  • springmvc概述及原理
  • 入门示例
  • SpringMVC工作流程
  • 映射路径-@RequestMapping
  • SpringMVC方法的返回值
  • 数据绑定

一. SpringMVC概述及原理

1. SpringMVC是什么

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),[Struts 2](https://baike.baidu.com/item/Struts 2/2187934)(一般老项目使用)等。

SpringMVC 已经成为目前最主流的 MVC 框架之一, 从 Spring3.0 的发布, 就已全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求。

2. MVC和三层架构

MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。


控制器(Controller):Servlet,控制器主要处理用户的请求

视图(View):HTML, JSP, 前端框架

模型(Model):逻辑业务程序(后台的功能程序), Service, Dao, JavaBean

JavaWEB发展史

Model1

所有的业务逻辑交给jsp单独处理完成,一个web项目只存在DB层和JSP层,所有的东西都耦合在一起,对后期的维护和扩展极为不利。

在这里插入图片描述

Model2 第一代

JSP Model2有所改进,把业务逻辑的内容放到了JavaBean中,而JSP页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但JSP还是把view和controller的业务耦合在一起。依然很不理想。

在这里插入图片描述

Model2 第二代(三层架构)

Model2第二代就是现在大力推广的和使用的mvc,将一个项目划分为三个模块,各司其事互不干扰,既解决了jsp所形成的耦合性,又增加了逻辑性、业务性以及复用性和维护性

表示层(web层):包含JSP,Servlet等web相关的内容

业务逻辑层(Service):处理业务,不允许出现servlet中的request、response。

数据层(Data Access Object):也叫持久层,封装了对数据库的访问细节。

其中 web层相当于mvc中的view+controller,Service层和dao层相当于mvc中的model。

在这里插入图片描述

3. SpringMVC 在三层架构的位置

MVC模式:(Model-View-Controller):为了解决页面代码和后台代码的分离.

在这里插入图片描述


二. 入门示例

1. 配置流程-基于XML的配置

1.1.搭建普通Maven项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用插件将项目转换为web项目

在这里插入图片描述

转换成功:

在这里插入图片描述

查看是否生成webapp目录和maven项目打包方式是否变为war

在这里插入图片描述

添加SpringMVC依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.0.6.RELEASE</version>
</dependency>

 

查看关系依赖图

在这里插入图片描述

1.2.在web.xml配置核心控制器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<!--spring核心(前端控制器)-->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>
	<servlet-mapping>		<!--只有*.form后缀的请求才会进入springmvc-->
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.form</url-pattern>
	</servlet-mapping>
</web-app>

 

1.3.创建一个Spring的配置文件

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.dfbz"/>

    <!--开启springmvc注解支持-->
    <mvc:annotation-driven/>
</beans>

 

mvc:annotation-driven 说明

在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。

在springmvc早期版本中需要我们自己加载springmvc的三大组件(现在我们使用的版本5.0.6会自动加载这三大组件)

**处理器映射器:RequestMappingHandlerMapping **

处理器适配器:RequestMappingHandlerAdapter

处理器解析器:ExceptionHandlerExceptionResolver

在早期的版本中使用 <mvc:annotation-driven> 自动加载这三大组件,但是高版本的不需要<mvc:annotation-driven>来加载

同时它还提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB,读写JSON的支持(Jackson)。我们处理响应ajax请求时,就使用到了对json的支持(配置之后,在加入了jackson的core和mapper包之后,不写配置文件也能自动转换成json)

springmvc配置文件说明

注意:默认的Spring配置文件放在WEB-INF下,名为{servlet-name}-servlet.xml

{servlet-name}指的是,核心控制器配置的名字

如:dispatcherServlet-servlet.xml

当请求被springmvc处理时,springmvc会去默认路径下加载xxxx-servlet.xml核心配置文件

在这里插入图片描述

但是我们在开发中一般都是把配置文件写在classes下的,我们可以在web.xml中设置springmvc配置文件的路径

<!--spring核心(前端控制器)-->
<servlet>
	<servlet-name>dispatcher</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!--配置springmvc配置文件的位置-->
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:dispatcher-servlet.xml</param-value>
	</init-param>
</servlet>
<servlet-mapping>		<!--只有*.form后缀的请求才会进入springmvc-->
	<servlet-name>dispatcher</servlet-name>
	<url-pattern>*.form</url-pattern>
</servlet-mapping>

 

1.4.创建一个业务控制器

package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController{

    //代表此方法的访问路径为/hello.form
    @RequestMapping("/hello.form")
    public ModelAndView hello(){
        
        ModelAndView mav=new ModelAndView();
        mav.addObject("msg","小标");
        mav.setViewName("/hello.jsp");

        return mav;
    }

}

 

1.5.创建一个返回的视图页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
   ${msg },欢迎您!
</body>
</html>

 

1.7. SpringMVC的工作流程

在这里插入图片描述

1、客户端发送请求给前端控制器(DispatcherServlet)

2、dispatcherServlet接收到请求调用HandlerMapping处理器映射器

3、处理器映射器根据请求的url找对应的处理器,生成处理器对象(handler)返回

4、dispatchServlet将handler传入处理器适配器执行

5、处理器适配器执行handler

6、执行完成最终封装一个ModelAndView

7、将ModelAndView返回给前端控制器

8、前端控制器将请求的路径交给视图解析器进行解析

9、最终封装一个View对象给dispatcherServlet,此View对象封装了响应参数

10、JSP页面渲染数据

11、响应客户端

1.8 SpringMVC源码分析

我们知道SpringMVC实质上是对servlet进行封装,让我们的开发更加简便

1. 准备工作

我们知道springmvc在工作开始之前会加载默认的处理器映射器、处理器适配器、处理器解析器等

可以在spring-webmvc-5.0.6.RELEASE.jar源码包下查看DispatcherServlet.properties文件看有哪些处理器是springmvc默认加载的

在这里插入图片描述

在这里插入图片描述

2. 查看DispatcherServlet的继承体系:

在这里插入图片描述

我们发现DispatcherServlet最终还是继承与HttpServlet,那么我们就直接找service方法吧!

经打断点发现,最终会走向DispacherServlet的doDispacher方法!

在这里插入图片描述

此时请求进入DispatcherServlet,按照我们画图分析的结果应该是把请求交给处理器映射器HandlerMapping最终返回一个Handler

3. 查看HandlerMapping接口:

在这里插入图片描述

4. 寻找HandlerMapping实现类:

在这里插入图片描述
在这里插入图片描述

接下来进入处理器适配器HandlerAdapter执行handler最终返回一个ModelAndView

5. 查看HandlerAdapter接口:

在这里插入图片描述

6. 查看HandlerAdapter实现类:

在这里插入图片描述
在这里插入图片描述

然后请求交给视图解析器进行解析最终返回一个View对象

7. 查看View接口:

在这里插入图片描述

8. 查看View实现类:

在这里插入图片描述
在这里插入图片描述

9. 查看View信息:

在这里插入图片描述

1.9.核心控制器

SpringMVC自带了拦截器请求的核心控制器.所以就可以在请求过来的时候,直接启动Spring框架

默认情况下,Spring容器是在核心控制器DispatcherServlet获得请求后才启动的.

能不能网站启动的时候,Spring容器就立刻启动.

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup><!-- 启动服务器的时候,Servlet就创建实例 --> 
</servlet>

 

三. Controller方法返回值

返回值


返回String

可以返回视图字符串,解析器会自动解析

@RequestMapping("/demo3_1")
public String demo3_1(){

    return "/success.jsp";           //直接返回字符串
}

 

返回ModelAndView

ModelAndView是SpringMVC帮我们提供的,即”模型和视图”

@RequestMapping("/demo3_2")
public ModelAndView demo3_2(){          //返回ModelAndView
    ModelAndView mav=new ModelAndView();
    mav.setViewName("success.jsp");
    mav.addObject("username","东方标准");
    return mav;
}

 

返回void

一般用于使用原生的Servlet对象或者ajax请求

@RequestMapping("/demo3_3")		//返回void(一般用于ajax)
public void demo3_2(HttpServletResponse response) throws IOException {          

    response.setContentType("text/html;charset=utf8");
    response.getWriter().write("东方标准");

}

 

转发和重定向


SpringMVC提供了一个 String 类型返回值之后会自动解析forward、redirect等特殊字符串

视图解析器配置的前缀和后缀解析不支持forward、redirect

:forward:代表转发request.getRequestDispatcher(url).forward(request,response)

:redirect:代表重定向response.sendRedirect(url)

@RequestMapping("/demo3_4")
public String demo3_4(Model model)  {          //转发

    System.out.println("执行啦!");
    model.addAttribute("username","东方标准");
    return "forward:/success.jsp";
}

 

@RequestMapping("/demo3_5")
public String demo3_5(HttpSession session)  {          //重定向
    session.setAttribute("password","admin");
    System.out.println("执行啦!");

    return "redirect:/success.jsp";
}

 

四. 映射路径-@RequestMapping

1. 探究RequestMapping

注解式处理器映射器,对类中标记了@ResquestMapping的方法进行映射。根据@ResquestMapping定义的url匹配@ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器。HandlerMethod对象中封装url对应的方法Method。

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
}

 

命名空间

按照我们传统的url写法不能很好的规定请求路径,即不能按照业务来区分请求

例如现在user需要定义一个findById,goods也需要定义一个findById,此时就会有冲突,针对这种现象我们可以在类上定义一个命名空间,即在类上使用@RequestMapping注解,类似于一级目录,以后访问此类下的任意资源都需要加上此目录

类上

请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录。 写的话需要以/开头。它出现的目的是为了使我们的 URL 可以按照模块化管理:

例如:

user模块:

/user/register

/user/update

/user/findById

goods模块:

/goods/add

/goods/update

/goods/findById

映射路径的有三种:标准的映射路径,带通配符的映射路径,带路径变量的映射路径

方法上

请求 URL 的第二级访问目录。

属性:

  • value:用于指定请求的 URL。 它和 path 属性的作用是一样的。
  • method:用于指定请求的方式。
  • params:用于指定限制请求参数的条件。 它支持简单的表达式。 要求请求参数的 key 和 value 必须和配置的一模一样。

params = {“userId”},表示请求参数必须有 userId,区分大小写

params = {“userId!=20”},表示请求参数中 id不能是 20。可以不携带userId参数,区分大小写

headers:用于指定限制请求消息头的条件。

package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController{

    public HelloController(){
        System.out.println("Hello创建了");
    }
    /*
    	代表此方法的访问路径为/hello.form,如果携带userId参数那么参数必须不能等于1
    	并且提交方式一定要为POST
    */
    @RequestMapping(value = "/hello.form",params = "userId!=1",method = RequestMethod.POST)
    public ModelAndView hello(){

        ModelAndView mav=new ModelAndView();
        mav.addObject("msg","小标");
        mav.setViewName("/hello.jsp");

        return mav;
    }

}

 

小结:

1.参数必须包括:params={“username”,“password”}

2.参数不能包括:params={“!userid”}

3参数值必须是指定的值:params={“username=zhangsan”})

4.参数值必须不是指定的值:params={“userid!=123”})

2.3. RESTFUL

所谓的路径变量,就是将参数放在路径里面,而不是放在?的后面

如:原get请求方法 /login.mvc?username=’zhangsan’&pwd=’123456’

路径变量写法:

/zhangsan/123456/login.form

2.3.1 什么是RESTFUL

REST(英文:Representational State Transfer,简称REST)RESTful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

2.3.2 RESTFUL示例:

示例 请求方式 效果
/user/1 GET 获取id=1的User
/user/1 DELETE 删除id为1的user
/user PUT 修改user
/user POST 添加user

请求方式有几种?7种

在这里插入图片描述

jsp、html,只支持get、post。

基于restful风格的url:

添加

http://localhost:8080/SpringMVC_01/user

提交方式: post

修改

http://localhost:8080/SpringMVC_01/user

提交方式:put

删除

http://localhost:8080/SpringMVC_01/user/101

提交方式:delete

查询

http://localhost:8080/SpringMVC_01/user/102

提交方式:get

五. 数据绑定

1. 数据绑定是什么

SpringMVC里面,所谓的数据绑定就是将请求带过来的表单数据绑定到执行方法的参数变量中,或将服务器数据绑定到内置对象,传递到页面

2. 自动绑定的数据类型

2.1 自动绑定数据类型

  • 基本数据类型:基本数据类型+String+包装类
  • 包装数据类型(POJO):包装实体类
  • 数组和集合类型:List、Map、Set、数组等数据类型

2.2 内置绑定数据自动绑定:

ServletAPI:

HttpServletRequest

HttpServletResponse

HttpSession

SpringMVC内置对象

Model

ModelMap

ModelAndView

Model和ModelMap默认都是存储了Request请求作用域的数据的对象

这个两个对象的作用是一样.就将数据返回到页面.

测试页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>测试ServletAPI绑定</h3>
<p><a href="/demo1.form"></a></p>
<h3>测试参数类型绑定</h3>
<p><a href="/demo2.form?username=zhangsan">属性参数绑定</a></p>

<h3>测试对象参数绑定</h3>
<form action="/demo3.form" method="post">
    <input type="text" name="username">
    <input type="text" name="password">
    <input type="text" name="address">

    <input type="submit" value="对象参数绑定">

</form>

<h3>测试数组类型绑定</h3>
<form action="/demo4.form" method="post">
    <input type="checkbox" value="1" name="ids">
    <input type="checkbox" value="2" name="ids">
    <input type="checkbox" value="3" name="ids">

    <input type="submit" value="数组类型绑定">
</form>

<h3>测试Pojo对象数据绑定</h3>
<hr>
<form action="/demo6.form" method="post">

    <h3>Pojo封装数组</h3>
    <input type="checkbox" value="1" name="ids">
    <input type="checkbox" value="2" name="ids">
    <input type="checkbox" value="3" name="ids">

    <br>

    <h3>Pojo封装user</h3>
    <input type="text" name="user.username">
    <input type="text" name="user.password">
    <input type="text" name="user.address">
    <br>

    <h3>Pojo封装list</h3>
    <input type="text" name="userList[1].name">
    <input type="text" name="userList[1].password">
    <input type="text" name="userList[1].address">
    <input type="text" name="userList[0].name">
    <input type="text" name="userList[0].password">
    <input type="text" name="userList[0].address">

    <br>

    <h3>Pojo封装map</h3>
    <input type="text" name="map['username']"><br>
    <input type="text" name="map['password']"><br>
    <input type="text" name="map['age']"><br>
    <input type="text" name="map['address']"><br>
    <input type="submit" value="Pojo对象参数绑定"><br>

</form>
</body>
</html>

 

测试Controller:

package com.dfbz.controller;

import com.dfbz.entity.Pojo;
import com.dfbz.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.List;

@Controller
public class DemoController {

    @RequestMapping("/demo1")            //自定义属性绑定
    public String demo1(HttpServletRequest request, HttpServletResponse response, HttpSession session){

        request.setAttribute("username","zhangsan");

        return "/success.jsp";
    }

    @RequestMapping("/demo2")            //属性参数绑定
    public String demo2(String username){

        System.out.println(username);

        return "/success.jsp";
    }

    @RequestMapping("/demo3")            //对象参数绑定
    public String demo3(User user){

        System.out.println(user);

        return "/success.jsp";
    }


    @RequestMapping("/demo4")            //数组参数绑定
    public String demo4(String[] ids){

        System.out.println(Arrays.toString(ids));
        return "/success.jsp";
    }

    @RequestMapping("/demo5")            //Pojo对象参数绑定
    public String demo5(Pojo pojo){

        System.out.println(pojo);

        return "/success.jsp";
    }
}

 

3. Post提交方式乱码解决

测试GET/POST提交中文数据

页面:

<h3>测试Post乱码</h3>
<form action="/demo" method="post">
    <input type="text" name="username">
    <input type="text" name="password">
    <input type="text" name="address">

    <input type="submit">
</form>

 

controller:

@RequestMapping("/demo7.form")            //Pojo对象参数绑定
public String demo7(User user){

    System.out.println(user);

    return "/success.jsp";
}

 

发现POST乱码

解决post提交乱码我们可以配置spring提供的过滤器

<!--解决Post提交中文乱码-->
<filter>
    <filter-name>characterEncoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <!--要使用的字符集,一般我们使用UTF-8(保险起见UTF-8最好)-->
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncoding</filter-name>
    <!--代表所有请求都经过编码处理-->
    <url-pattern>/*</url-pattern>
</filter-mapping>

 

4. SpringMVC常用注解

SpringMVC有一些数据是不能自动绑定,需要我们使用它提供的注解强制绑定.

遇到需要强制绑定的几种情况

a. 默认参数绑定的是表单数据,如果数据不是来自表单(如restful),那么必须需要强制绑定

b. 数据是来自表单的,但是参数名不匹配,那么也需要强制绑定

c. 数据是来自表单的,但是需要将数据绑定在Map对象里面,需要强制绑定

4.1. @PathVariable:绑定路径参数

这个注解是绑定路径参数的.

/**
 * http://localhost:8080/20/zhangsan/demo9.form
 * @param id
 * @param username
 * @return
 */
@RequestMapping("/{id}/{username}/demo9")            //@PathVariable绑定restful请求
public String demo9(
    @PathVariable("id") Integer id,@PathVariable("username") String username
    ){

    System.out.println(id);
    System.out.println(username);

    return "/success.jsp";
}

 

<a href="/20/zhangsan/demo9.form">测试restful风个绑定</a>

 

4.2. 通过@RequestParam绑定表单数据

接收的参数的变量名与表单的name属性不一样

/**
 * http://localhost:8080/demo8.form?name=zhangsan
 * @param username
 * @return
 */
@RequestMapping("/demo8")            //@RequestParam强制数据类型绑定
public String demo8(@RequestParam("name") String username) {

    System.out.println(username);

    return "/success.jsp";
}

 

<a href="/demo8.form?name=zhangsan">测试强制类型绑定</a>

 

4.3. @CookieValue获得Cookie值的注解

/**
* 获得JSP 页面,JSESSIOINID这个Cookie值
* @param cookevalue
*/
@RequestMapping("/demo10")
public void getcookie(@CookieValue(value="JSESSIONID") String cookevalue){
    //输出Cookie
    System.out.println(cookevalue);
}

 

<a href="/demo10.form">测试@CookieValue注解</a>

 

4.4. @RequestHeader获得指定请求头的值

@RequestMapping("/demo11")
//获取请求头host的值封装到value中
public void demo10(@RequestHeader("host")String value){

    System.out.println(value);
}

 

<a href="/demo11.form">测试@RequestHeader注解</a>

 

4.5 @SessionAttributes 注解

把Model和ModelMap中的指定的key或者指定的属性的值也存入一份进session域

package com.dfbz.controller;

import com.dfbz.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;

import javax.servlet.http.HttpServletRequest;

@Controller
/**
 * names: 代表此类中model/modelMap的username属性将会添加到一份进入session
 * types: 此类中指定的类型会添加一份到session中
 */
@SessionAttributes(names = {"username"},types ={User.class,String.class,Integer.class} )
public class Demo2Controller {

    @RequestMapping("/demo12.form")
    public String demo12(Model modelMap) {
        modelMap.addAttribute("username","zhangsan");
        modelMap.addAttribute("password","admin");
        modelMap.addAttribute("age",20);
        User user=new User();
        user.setUsername("xiaodong");
        modelMap.addAttribute("user",user);
        return "/success.jsp";
    }
}

 

<a href="/demo12.form">测试@SessionAttribute注解</a>

 

@SessionAttribute注解:

从session中获取一个值封装到参数中

/**
 * @SessionAttribute:从session中获取一个值
 * @param username
 * @param user
 * @return
 */
@RequestMapping(value = "/demo6")
public String demo5(@SessionAttribute("password") String username,@SessionAttribute("user") User user){
    System.out.println(username);

    return "/success.jsp";
}

 

5. 格式化参数类型

SpringMVC之所以能够帮我们实现自动数据类型转换是因为SpringMVC提供了非常多的转换器(Converter)

例如:

源类型 转换之后的类型 对应转换器
java.lang.Boolean java.lang.String ObjectToStringConverter
java.lang.Number java.lang.Character NumberToCharacterConverter
java.lang.String java.lang.Boolean StringToBooleanConverter

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

发现他们都实现Converter接口,如果我们需要之定义转换器必须实现Converter接口

案例:

实现日期的转换

实体类:

public class User {
    private Integer id;
    private String username;
    private String password;
    private String address;
    private Date birthday;
}

 

表单:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<form action="/testConverter.form">
    <input type="text" name="username">
    <input type="text" name="password">
    <input type="text" name="address">
    <input type="text" name="birthday">

    <input type="submit">
</form>

</body>
</html>

 

controller:

@RequestMapping("/testConverter.form")
public String testConverter(User user) {
    System.out.println(user);
    return "/success.jsp";
}

 

转换器类:

package com.dfbz.converter;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Converter<传入进来的类型,转换之后的类型>
 */
public class MyConverter implements Converter<String,Date> {
    @Override
    public Date convert(String str) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(str);
            return date;

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }
}

 

dispatcher-servlet.xml配置

<!--在SpringMVC配置的转换器中添加我们自定义的转换器-->
<bean id="myConverters" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <!-- 配置多个转换器 -->
    <property name="converters">
        <set>
            <!-- 配置转换器(自定义转化器类) -->
            <bean class="com.dfbz.converter.MyConverter"></bean>
        </set>
    </property>
</bean>

<!--开启springmvc注解支持并重新指定转换器-->
<mvc:annotation-driven conversion-service="myConverters"/>

 

六. Controller的生命周期

Spring框架默认创建的对象是单例.所以业务控制器是一个单例对象.

SpringMVC提供了,request,session ,globalsession三个生命周期

  • request:每次新的请求,创建一个新的实例.
  • session:每次会话创建一个新的实例. 就是同一个浏览器,就使用同一个实例
  • globalsession:基于集群的session

每个Session创建一个实例

package com.dfbz.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
//@Scope("request")           //代表每次请求都会创建一个新的Demo4Controller对象
//@Scope("session")               //代表每次创建session就会创建一个Demo4Controller对象
public class Demo4Controller {

    public Demo4Controller(){
        System.out.println("Demo4Controller创建啦!");
    }

    @RequestMapping("/demo4_1")
    public String demo4_1(){

        return "/success.jsp";
    }


}

at.support.FormattingConversionServiceFactoryBean”>

<mvc:annotation-driven conversion-service=“myConverters”/>

六. Controller的生命周期

Spring框架默认创建的对象是单例.所以业务控制器是一个单例对象.

SpringMVC提供了,request,session ,globalsession三个生命周期

  • request:每次新的请求,创建一个新的实例.
  • session:每次会话创建一个新的实例. 就是同一个浏览器,就使用同一个实例
  • globalsession:基于集群的session

每个Session创建一个实例

package com.dfbz.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
//@Scope("request")           //代表每次请求都会创建一个新的Demo4Controller对象
//@Scope("session")               //代表每次创建session就会创建一个Demo4Controller对象
public class Demo4Controller {

    public Demo4Controller(){
        System.out.println("Demo4Controller创建啦!");
    }

    @RequestMapping("/demo4_1")
    public String demo4_1(){

        return "/success.jsp";
    }


}

作者:易兮科技 | 来源:https://blog.csdn.net/m0_47157676

赞(0) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 » SSM第七讲 SpringMVC概述和基础知识详解

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏