Spring第四天-SpringMVC第一天

Spring04

回顾

aop:面向切面编程(oop的补充):在程序运行期间,在不破坏源代码的情况下,实现对业务方法的增强,让开发者只关注业务部分
常用场景:
	打印日志
	测试程序运行时间
	控制事务
	...
导入依赖:spring-context和aspectjweaver
aop-xml方式
	配置切面
		切入点+通知
	通知类型:
        before
        afterReturning
        afterThrowing
        after
        around 
        开发中一般使用环绕通知可以保证其余代码的执行顺序,可以使用ProceedingJoinPoint获取目标方法
        	别忘记:1.返回值 2.异常
	切点表达式
		execution([修饰符] 返回值类型 包名.类名.方法名(参数类型))
		execution(* com.itheima.service..*.*(..)) 
aop的xml+注解
	通过@Aspect声明某个组件为通知类
	通过@Pointcut("切入点表达式")作用在某个方法上抽取切入点表达式
	通过注解在通知类中的方法上进行声明通知类型
        @Before("切入点表达式或者带有切点表达式的方法名")
        @AfterReturning("")
        @AfterThrowing("")
        @After("")
        @Around("")
	在配置文件中开启组件扫描和aop注解支持(自动代理)
    	<aop:aspectj-autoproxy/>
aop纯注解
	自定义注解类
		@EnableAspectJAutoProxy

JDBCTemplate:
	spring提供的dao层的框架,使用的时候和DBUtils差不多
	new JdbcTemplate(DataSource ds)
	方法:
		update
		query
		queryForObject
			查询的时候若需要将结果封装成指定的javabean对象,使用new BeanPropertyRowMapper<>(User.class)
	整合spring
		把JdbcTemplate交给spring管理

内容介绍

spring的事务(非常简单,非常常用)

  • 编程式事务–没人用
  • 声明式事务–必须掌握
    • xml
    • 注解

springmvc:web层框架

  • 接受请求(封装请求参数)
  • 生成响应(转发,重定向,打印)

一 Spring的事务

1 事务回顾

事务就是一件完整的业务(事情),它有可能包含多个操作,这些操作要么全部成功,要么全部失败.

事务的特性:

ACID

原子性:事务是最小单元,不可切割,

一致性:事务执行前后状态要和业务状态保持一致

隔离性:事务执行的时候尽量隔离起来,不受其他事务干扰

持久性:事务一旦提交.就会写入磁盘中


不考虑隔离性会产生那些问题

脏读:一个事务读取到另外一个事务未提交的脏数据

不可重复读:在一次事务中,两次读取的结果不一致,针对是对记录进行修改操作

虚读(幻读):在一次事务中,两次统计的结果不一致,针对的是对记录的插入和删除操作.


隔离级别

通过设置数据库的隔离级别来避免上述的问题

  • read uncommitted : 读未提交,任何读问题都避免不了,效率是最高的
  • read commmitted : 读已提交,可以避免脏读, oracle默认
  • repeatable read : 可重复读,可以避免脏读和不可重复读, mysql默认
  • serializable : 串行化,可以避免所有的读问题,效率是最低

开发中一般使用数据库默认的隔离级别


在spring中事务有两种方式:

  • 编程式事务:事务代码和业务代码耦合在一起.没人用
  • 声明式事务:通过配置的方式就可以将事务添加进来.
    • xml方式
    • 注解方式
      • xml+注解
      • 纯注解

2 编程式事务【了解】

开发者直接把事务的代码和业务代码耦合到一起,在实际开发中不用。

需要知道的几个类或者接口

PlatformTransactionManager

平台事务管理器,是一个接口, 提交事务和回滚事务

三个常用或常见的实现类,需要导入spring-orm包才能显示出来hibernate和jpa

* jdbc 和 mybatis
		DataSourceTransactionManager
* hibernate
		HibernateTransactionManager
* jpa(spring data)
		JpaTransactionManager
* 分布式事务
		JtaTransactionManager

TransactionDefinition

事务定义,用来定义事务的:隔离级别,执行时候的超时时间,是否只读,传播行为

事务隔离级别

1. 读未提交	【会出现脏读、不可重复读、幻读问题】
    read_uncommitted
   
2. 读已提交【会出现不可重复读、幻读问题】
    read_committed

3. 可重复读【会出现幻读问题】
    repeatable_read

5. 串行化 【相当于锁表】
    serializable

事务传播行为

事务传播行为指的就是当一个业务方法被另一个业务方法调用时,应该如何进行事务控制。

业务层A方法,调用业务层B方法【主要角色】

* REQUIRED【必须】默认值 运行的时候必须有事务
	A方法调用C方法,如果A方法没有事务,C方法创建一个事务,如果A方法有事务,那么C方法直接使用A方法的事务控制
	
* SUPPORTS【支持】运行的时候 有就用 没有就不用
	A方法调用C方法,如果A方法没有事务,C方法也没有事务,如果A方法有事务,那么C方法直接使用A方法的事务控制

TransactionStatus

事务的运行状态

总之记住一句话:代码在操作的时候,先使用TransactionDefinition定义事务的规则(隔离级别,传播行为,超时时间,是否只读),使用PlatformTransactionManager进行事务的控制,事务的运行状态都会保存在TransactionStatus中.

3 声明式事务【重点】

事务的代码是固定的,spring已经将事务的代码封装好了,我们需要做的操作:

  1. 给那些方法(切入点)添加事务,
  2. 事务的运行规则如何

开发者采用配置的方式来实现的事务控制,业务代码与事务代码实现解耦合,使用的AOP思想。

底层使用的aop+编程式事务

因为底层使用的aop,所以别忘了导入aspectjweaver包

别忘记配置事务管理器

  • 我们使用的dao层解决方案是JdbcTemplate或者mybatis,我们使用的DataSourceTransactionManager

xml配置声明式事务(常用)

需求

​ 使用spring声明式事务控制转账业务。

步骤分析:

  1. 复制昨天最后一个模块,重命名为spring04_1_tx_xml
  2. 导入依赖aspectjweaver
  3. 修改配置文件beans.xml
    • 加载properties配置文件
    • 组件扫描
    • 配置数据源
    • 配置jdbcTemplate
    • 配置事务管理器
      • 注入数据源
    • 配置事务运行规则(属性)
      • 那些方法执行的时候使用的隔离级别,传播行为,超时时间及是否只读等
    • aop配置
      • 定位到service中的方法上,使用spring内置的通知结合定义好的规则运行代码

spring配置文件

<!--配置事务管理器 id不建议随便起,建议叫transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--注入数据源-->
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--
        配置事务规则(属性)
            给那些方法规定它的隔离级别,传播行为,超时时间,是否只读
            id属性:给规则起个名字
            transaction-manager属性:指定使用那个事务管理器,默认值为transactionManager
    -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <!--
                name属性:指定方法名称的,支持通配符*
                propagation属性:指定事务传播行为,一般使用默认值,若是查询建议使用supports
                isolation属性:指定事务的隔离级别,一般使用默认值
                timeout属性:设置超时时间,一般使用默认值-1:永不超时
                read-only属性:设置事务是否只读.查询操作建议设置为只读.其他使用默认值false
            -->
        <tx:method name="find*" propagation="SUPPORTS" isolation="DEFAULT" timeout="-1" read-only="true"/>
        <!--其他的方法都使用默认值-->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!--aop配置-->
<aop:config>
    <!--定义切入点-->
    <aop:pointcut id="service_pc" expression="execution(* com.itheima.service..*.*(..))"/>
    <!--配置切面-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="service_pc"/>
</aop:config>

去掉注释,使用默认值

<!--配置事务管理器 id不建议随便起,建议叫transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--注入数据源-->
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="find*" propagation="SUPPORTS"read-only="true"/>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!--aop配置-->
<aop:config>
    <!--定义切入点-->
    <aop:pointcut id="service_pc" expression="execution(* com.itheima.service..*.*(..))"/>
    <!--配置切面-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="service_pc"/>
</aop:config>

xml配置事务的好处:一劳永逸

注解+xml配置声明式事务

步骤分析:

  1. 复制spring04_1_tx_xml,重命名为spring04_2_tx_xml_anno
  2. 删除beans.xml中tx:advice标签和aop:config标签
  3. 在beans.xml中开启事务的注解支持 tx:annotation-driven
  4. 在需要添加事务的类上或者方法上通过@Transactional配置事务

spring配置文件添加了注解支持

<!--开启事务注解支持-->
<tx:annotation-driven transaction-manager="transactionManager"/>

在service类上或者service中方法上添加了注解

纯注解【了解】

步骤分析:

  1. 复制spring04_2_tx_xml_anno,重命名为spring04_3_tx_anno
  2. 创建一个配置类SpringConfig
    • 添加注解
      • @Configuration
      • @ComponentScan
      • @PropertySource
      • @Import 导入其他的配置类
      • @EnableTransactionManager //开启事务注解支持
  3. 创建一个配置类DaoConfig
    • 配置数据源
    • 配置JdbcTemplate
  4. 创建一个配置类TXConfig
    • 配置事务管理器
  5. 删除beans.xml,修改测试类

@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:db.properties")//只能使用一次,建议写在主配置类上或者对应的标签写在主配置文件中
@EnableTransactionManagement //开启事务注解支持
@Import({DaoConfig.class,TXConfig.class})
public class SpringConfig {
}
public class DaoConfig {

    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;


    @Bean("dataSource")
    public DataSource createDS(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }

    @Bean
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }
}
public class TXConfig {

    @Bean("transactionManager")
    public PlatformTransactionManager createPTM(DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
}

二 SpringMVC简介

1 回顾MVC模式

只是一种思想,将业务代码和信息展示分离.所有后台语言都要遵守这个思想

image-20200919004815592

2 springMVC

​ springMVC是按照MVC设计模式开发的轻量级web框架,他也是spring framework家族的一部分。

​ springMVC封装了servlet公共的特性,使开发者只需要关注业务的私有特性(通过一个普通的类),来提高开发效率。

​ web层框架中封装共有的特性在前端控制器中完成,前端控制器中肯定要获取request和response对象,所以前端控制器一般是servlet或者filter

  • springmvc的前端控制器就是一个Servlet:DispatcherServlet
    • 配置普通的javabean就可以完成请求的处理操作

扩展:

  • strust2的前端控制器是一个Filter:Struts2PrepareAndExecuteFilter

学习springmvc:

  • 如何封装请求参数(包括文件上传)
  • 如何生成响应信息
  • 拦截器:类似于web中过滤器

3 快速入门

需求

在index.jsp上有一个连接(/springmvc/hello),点击连接,在控制台打印一句话,转发到/WEB-INF/pages/success.jsp

步骤分析

  1. 建web模块,导依赖:servlet,jsp,spring-webmvc
  2. 在index.jsp上新建一个连接,在web-inf下新建pages目录,新建一个success.jsp
  3. 在web包下新建一个类:A_HelloController,编写一个方法:sayHello
    • 给类上添加一个注解 : @Controller
    • 给方法添加一个注解 : @RequestMapping(“hello”)
      • 返回值为要转发的路径
  4. 在resources目录新建一个spring的配置文件:文件名字自定义,建议springmvc.xml
    • 开启组件扫描
    • 开启mvc注解支持
    • 暂时不配-视图解析器
  5. 在web.xml中配置前端控制器:DispatcherServlet
    • servlet
      • 配置名字
      • 通过servlet的初始化参数配置springmvc配置文件的路径
      • 修改servlet的初始化时机 load-on-startup
    • servlet-mapping
      • 配置路径暂时为 /

代码实现

web模块的pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <!--测试和编译环境下使用,运行时使用servlet容器的jar包-->
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
</dependencies>

controller代码

@Controller //将此类的对象加入springmvc容器
public class A_HelloController {

    @RequestMapping("hello")//配置处理的路径
    //@RequestMapping("/hello")
    public String sayHello(){
        System.out.println("收到了请求");

        //返回值转发的路径
        //return "/WEB-INF/pages/success.jsp";

        //当在springmvc.xml中配置了视图解析器之后,路径就可以下面的方式
        return "success";
    }
}

springmvc.xml

<!--开启组件扫描-->
<context:component-scan base-package="com.itheima.web"/>

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

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

web.xml

<!--前端控制器-->
<servlet>
    <servlet-name>DispatcherServlet</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的初始化时机-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <!--处理除了jsp之外所有的请求-->
    <url-pattern>/</url-pattern>
</servlet-mapping>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yPmE33Hq-1622723497303)(spring04.assets/image-20200919151337918.png)]

4 快速入门执行流程

三 SpringMVC组件概述

1 springmvc框架执行流程(面试题)

项目启动的时候

  1. web.xml中配置了前端控制器,且把它的初始化时机修改成随着项目启动而进行初始化
  2. 加载并解析servlet初始化参数中配置的springmvc.xml
  3. 创建springmvc容器(spring容器)
  4. 扫描web包下的所有有@Component和衍生注解的类,创建对象,加入springmvc容器中
  5. 创建处理器映射器对象和处理器适配器对象,并放入springmvc容器中(mvc注解支持)
  6. 处理器映射对象,会把controller中含有@RequestMapping的方法找到,会形成一种映射关系
    • 路径名称—类中方法名
    • 路径名称—拦截器(类似于过滤器)
  7. 创建视图解析器对象,放入springmvc容器中

请求来的时候

  1. 请求先到达前端控制器,
  2. 前端控制器拿到请求之后会访问处理器映射器:"/hello"这个请求会执行那些拦截器和controller(处理器)
  3. 处理器映射器将这个请求对应的拦截器和处理器都返回:例如 com.itheima.web.ctrl.AHelloCTRL.sayHello
  4. 前端控制器拿到返回处理的执行链之后,找到处理适配器:“你去执行这些拦截器和处理器吧”
  5. 处理器适配器就去找到指定的拦截器和处理器,然后执行他们
  6. 处理器执行完毕之后,返回了一个值.
  7. 处理器适配器拿到返回值之后,将返回值包装成ModelAndView对象,然后将对象返回给前端控制器
    • model中存放的域中的数据
    • view中存放是跳转的(逻辑)视图,例如:success
  8. 前端控制器收到modelandview对象后,找到视图解析器,说:你给我看看success对应是那个(物理)视图
  9. 视图解析器拿到之后,将前缀和后缀拼接好,返回view对象,对应的是:/WEB-INF/pages/success.jsp
  10. 前端控制器拿到物理视图之后,转发或者重定向到/WEB-INF/pages/success.jsp,且把域中的数据携带过去,物理视图编译然后运行生成响应信息,然后将响应信息返回给服务器.
  11. 服务器拿到响应之后生成响应行、头、体,将响应返回给浏览器

2 三大组件

  1. 处理器映射器(mvc注解支持)
    负责将url路径和方法上的路径产生映射关系,返回处理器执行链
  2. 处理器适配器(mvc注解支持)
    根据执行路径查找多个处理器中的某一个方法,执行业务逻辑,返回ModelAndView
  3. 视图解析器(在springmvc.xml中配置)
    将逻辑视图解析为view对象(真实资源文件对象)

我们需要做的事情:

  1. 配置前端控制器(web.xml),视图解析器,mvc注解支持
  2. 编写处理器(controller)和 视图(jsp)

3 最最常用注解解析

@Controller

作用在web层的类上,将这个类对应的对象创建好,且放入springmvc容器中

@RequestMapping

作用:将请求的路径和某个类中的某个方法形成映射关系

常见和常用的属性:

  • value属性:配置访问路径的
  • method属性:配置请求的方式 例如:get或者post等
  • param属性(了解):配置请求路径中必须包含的参数信息,若不满足就会报错:400(参数错误)

这个注解既可以作用在类上也可以作用在方法上.

  • 若作用在类上,这个路径就是一级路径,若方法上也有,方法上的路径就是二级路径.最终的访问路径是"/一级路径/二级路径"
  • 方便分模块开发
    • 例如:一级路径 /user或者/order,二级路径随便编写都不会重复的路径
<a href="${pageContext.request.contextPath}/requestMapping/test1">b_requestmapping-value属性</a><br/>
<a href="${pageContext.request.contextPath}/requestMapping/test2">b_requestmapping-method属性</a><br/>
<a href="${pageContext.request.contextPath}/requestMapping/test3">b_requestmapping-param属性-没有username报错400</a><br/>
<a href="${pageContext.request.contextPath}/requestMapping/test3?username=tom">b_requestmapping-param属性-有username参数不报错</a><br/>
@Controller
@RequestMapping("requestMapping")
public class B_RequestMappingController {

    @RequestMapping("test1")
    public String test1(){
        System.out.println("requestMapping的路径");
        return "success";
    }

    //method属性:只能处理那些请求方式
    @RequestMapping(value="test2",method = {RequestMethod.POST,RequestMethod.GET})
    public String test2(){
        System.out.println("requestMapping的method属性");
        return "success";
    }

    //param属性是用来指定请求的路径中必须包含的请求信息
    @RequestMapping(value="test3",params = "username")
    public String test3(){
        System.out.println("requestMapping的param属性");
        return "success";
    }
}

四 SpringMVC的请求

1 接收请求参数

  • 基本数据类型和String类型(请求参数的名称和方法变量名称保持一致)
  • 对象类型(请求参数的名称和对象中属性名保持一致)
  • 数组类型或者以逗号分隔字符串
  • 对象中的集合类型.使用ognl表达式,将表单中的数据封装给对象中的集合类型
<a href="${pageContext.request.contextPath}/param/test1?username=tom&age=18">c_请求参数_封装简单类型</a><br/>
<form action="${pageContext.request.contextPath}/param/test2" method="post">
    <fieldset>
        <legend>c_请求参数_封装成javabean</legend>
        银行名称:<input type="text" name="bankName"/><br/>
        银行余额:<input type="text" name="money"/><br/>
        <input type="submit" value="提交">
    </fieldset>
</form>

<form action="${pageContext.request.contextPath}/param/test3" method="post">
    <fieldset>
        <legend>c_请求参数_多选封装成数组</legend>
        <input type="checkbox" name="ids" value="1">id:1 name:xx<br/>
        <input type="checkbox" name="ids" value="2">id:2 name:xx<br/>
        <input type="checkbox" name="ids" value="3">id:3 name:xx<br/>
        <input type="checkbox" name="ids" value="4">id:4 name:xx<br/>
        <input type="checkbox" name="ids" value="5">id:5 name:xx<br/>
        <input type="checkbox" name="ids" value="6">id:6 name:xx<br/>
        <input type="submit" value="删除选中">
    </fieldset>
</form>

<form action="${pageContext.request.contextPath}/param/test4" method="post">
    <fieldset>
        <legend>c_请求参数_多选封装成用逗号分隔的字符串</legend>
        <input type="checkbox" name="ids" value="1">id:1 name:xx<br/>
        <input type="checkbox" name="ids" value="2">id:2 name:xx<br/>
        <input type="checkbox" name="ids" value="3">id:3 name:xx<br/>
        <input type="checkbox" name="ids" value="4">id:4 name:xx<br/>
        <input type="checkbox" name="ids" value="5">id:5 name:xx<br/>
        <input type="checkbox" name="ids" value="6">id:6 name:xx<br/>
        <input type="submit" value="删除选中">
    </fieldset>
</form>

<form action="${pageContext.request.contextPath}/param/test5" method="get">
    <fieldset>
        <legend>c_请求参数_封装成javabean及其javabean中的集合</legend>
        姓名:<input type="text" name="username"/><br/>
        年龄:<input type="text" name="age"/><br/>

        银行名称1:<input type="text" name="accountList[0].bankName"/><br/>
        银行余额1:<input type="text" name="accountList[0].money"/><br/>

        银行名称2:<input type="text" name="accountList[1].bankName"/><br/>
        银行余额2:<input type="text" name="accountList[1].money"/><br/>

        银行名称3:<input type="text" name="accountMap['aa'].bankName"/><br/>
        银行余额3:<input type="text" name="accountMap['aa'].money"/><br/>
        <input type="submit" value="提交">
    </fieldset>
</form>
public class User {
    private String username;
    private int age;

    private List<Account> accountList;
    private Map<String,Account> accountMap;
	//自己补全get,set和tostring
}
public class Account {
    private String bankName;
    private Double money;
    //自己补全get,set和tostring
}
@Controller
@RequestMapping("param")
public class C_ParamController {
    //封装简单类型,只需要在方法中声明请求参数即可,保证请求参数名字和方法的参数名字一致
    @RequestMapping("test1")
    public String test1(String username,int age){
        System.out.println(username+"--"+age);
        return "success";
    }


    //将请求参数封装javabean,只需要在方法参数中声明参数即可
    @RequestMapping("test2")
    public String test2(Account account){
        System.out.println(account);
        return "success";
    }

    //将多选提交过来的值封装成数组或者字符串,方法的参数名称必须和请求参数的名字一致
    @RequestMapping("test3")
    public String test3(int[] ids){
        System.out.println(Arrays.toString(ids));
        return "success";
    }
    @RequestMapping("test4")
    public String test3(String ids){
        System.out.println(ids);
        return "success";
    }

    @RequestMapping("test5")
    public String test5(User user){
        System.out.println(user);
        System.out.println(user.getAccountList());
        System.out.println(user.getAccountMap());
        return "success";
    }
}

2 post请求中文过滤器

spring已经提供了一个过滤器CharacterEncodingFilter,我们只需要去web.xml中配置即可

<!--配置字符编码过滤器-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <!--指定post请求的编码-->
        <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>

3 类型转换

如果我们提交的是一个字符串类型的日期,那么springMVC框架会自动转换为日期类型,要求:字符串格式必须为:yyyy/MM/dd,如果不是此格式那么转换失败,但是对于国内用户而言习惯日期格式:yyyy-MM-dd,这个时候就需要我们进行类型转换

方式1:在需要转换的字段上面添加注解

方式2:自定义转换器

1. 编写一个类 实现Converter接口(原来的类型,目标类型),重写转换的方法
2. 在springMVC配置文件中配置自定义转换器服务
3. 进行测试	
public class MyString2DateConverter implements Converter<String,Date> {
    @Override
    //导入hutools依赖
    public Date convert(String source) {
        if (StringUtils.isNotBlank(source)) {
            try {
                return DateUtil.parse(source,"yyyy-MM-dd");
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值