SpringMVC全注解环境搭建

    科技2025-01-14  17

    源代码:

    链接:https://pan.baidu.com/s/1Lxb-riH–YQNIy3c0i8pFA 提取码:y3aq 文档地址:https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/

    一、基本环境

    jdk 1.8IDEA 2019Maven 3.6.3Tomcat 9.0

    二、准备工作

    2.1 建立Maven工程

    2.1.1 打开IDEA,选择【Create New Project】–> 【Maven】–> 【勾选Create from archetype】–>【maven-archetype-webapp】

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yv4oukqV-1602078341144)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/1.jpg)]

    2.1.2 给项目命名,然后一直下一步:【Next】

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HjcwL14w-1602078341146)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/2.jpg)]

    2.2 项目的基本结构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-akIdZ3Mf-1602078341149)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/3.jpg)]

    2.3 导入基础的依赖

    <!--spring核心依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.20.RELEASE</version> </dependency> <!--SpringMVC依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.20.RELEASE</version> </dependency> <!--Servlet 依赖,这里指定由Tomcat提供--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>

    三、编写配置类

    3.1 创建一个 WebAppConfig 配置类,作为 SpringMVC 的配置类

    /** * @Configuration 标识该类是一个配置类 * @EnableWebMvc 相当于在xml中配置 <mvc:annotation-driven/> * WebMvcConfigurerAdapter 继承该抽象类相当于指定该配置类是SpringMVC配置类 */ @Configuration @EnableWebMvc public class WebAppConfig extends WebMvcConfigurerAdapter { }

    3.2 创建一个RootConfig 配置类,作为 Spring 的配置类

    @Configuration public class RootConfig { }

    3.3 创建一个 MyWebAppInitializer 作为核心启动类,用于加载 SpringMVC 和 Spring 的配置类

    public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // 这里指定 Spring 的核心配置类 @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{RootConfig.class}; } // 这里指定 SpringMVC 的核心配置类 @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{WebAppConfig.class}; } // 这里指定 DispatcherServlet 的拦截规则,我们这里拦截所有请求 @Override protected String[] getServletMappings() { return new String[]{"/"}; } }

    四、编写测试项目

    4.1 编写Controller

    4.1.1 这里编写一个 UserController

    @Controller public class UserController { @Autowired private IUserService service; @RequestMapping(value = "/user") @ResponseBody public String getUserById(@RequestParam(value = "id", defaultValue = "0", required = false) int id) { User user = service.getUserById(id); return user.toString(); } }

    4.1.2 我们需要将 UserController 扫描到容器中

    这里我们使用@ComponentScan将组件扫描进 SpringMVC 容器,因此我们需要在WebAppConfig配置类添加该注解

    @ComponentScan(basePackages = "com.shph.controller")

    4.2 编写 Service

    4.2.1 这里编写一个 IUserService 接口并完成其实现类

    // 接口类 public interface IUserService { User getUserById(int id); } // 实现类 @Service public class UserServiceImpl implements IUserService { @Autowired private IUserDao userDao; @Override public User getUserById(int id) { return userDao.selectUserById(id); } }

    4.2.2 将 UserServiceImpl 扫描到容器中

    这里我们将 UserServiceImpl 扫描到 Spring 容器中,因此我们需要在 RootConfig配置组件扫描注解

    @ComponentScan(basePackages = "com.shph", excludeFilters = @ComponentScan.Filter({Controller.class}))

    4.2 编写 Dao

    4.2.1 这里编写一个 IUserDao 接口并完成其实现类

    // 接口类 public interface IUserDao { User selectUserById(int id); } // 实现类 @Repository public class UserDaoImpl implements IUserDao { // 这里向使用 Map 提供数据,暂时不去数据库查询数据 private static Map<Integer, User> map = new HashMap<>(); static { map.put(0, new User(0, "jack", 18, "man")); map.put(1, new User(1, "tom", 30, "man")); map.put(2, new User(2, "翠花", 20, "女")); map.put(3, new User(3, "张三", 22, "男")); } @Override public User selectUserById(int id) { return map.get(id); } }

    4.2.2 将 UserDaoImpl 扫描到容器中

    在编写 UserService 时,我们指定的组件扫描注解已经可以将该实例扫描到Spring容器了,因此不需要再次配置。

    4.4 实体 User

    // 这里使用了 lombok 创建,用于简化实例类 @Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String name; private int age; private String gender; }

    4.5 配置 Tomcat【Tomcat需要我们提前安装好】

    4.5.1 在IDEA 右上角有个 Add Configuration…,进入这里

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rHldE0gQ-1602078341152)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/4.jpg)]

    4.5.2 点击’+‘号,选择’Tomcat Server’,然后选择‘Local’,点击 ok 即可

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R7uxqvci-1602078341155)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/5.jpg)]

    4.5.3 配置Tomcat参数

    这里重点时搭建SpringMVC全注解项目,有关Tomcat的配置就不再细说。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fJifLjPT-1602078341156)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/6.jpg)]

    4.5.4 完成配置,然后启动Tomcat

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T4nKh0sh-1602078341158)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/7.jpg)]

    4.5.5 使用浏览器访问测试

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ONZCbQu7-1602078341159)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/8.jpg)]

    五、中文乱码问题

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GCyWh49p-1602078341161)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/9.jpg)]

    我们可以看到,查询id=3的用户会出现中文乱码问题

    // 实际上我们的数据是这样的 map.put(3, new User(3, "张三", 22, "男"));

    我们再看看浏览器的【响应信息】,我们可以看到响应的数据编码格式并不是UTF-8

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WB9D2Syu-1602078341162)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/10.jpg)]

    5.1 配置 CharacterEncodingFilter

    以前我们在web.xml会配置 CharacterEncodingFilter 过滤器,然而现在我们没有web.xml配置文件,我们又该如何配置?

    我们来到我们的MyWebAppInitializer,我们知道MyWebAppInitializer继承了抽象类AbstractAnnotationConfigDispatcherServletInitializer,我们需要重写里面的方法void onStartup(...)

    @Override public void onStartup(ServletContext sc) throws ServletException { super.onStartup(sc); // 调用父类方法 // 注册 CharacterEncodingFilter 过滤器 CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setForceEncoding(true); filter.setEncoding("UTF-8"); FilterRegistration.Dynamic encodingFilter = sc.addFilter("filter", filter); // 配置过滤规则 '/*' 拦截所有请求 encodingFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*"); }

    在ServletContext类里面提供了对servlet,filter,listener的组成方法

    sc.addServlet(); sc.addFilter(); sc.addListener();

    好了,我们配置好 CharacterEncodingFilter 过滤器后,是不是觉得可以解决中文乱码了?我们在访问一下看看

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kKVhFFEK-1602078341163)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/11.jpg)]

    怎么回事???

    这是因为在返回消息的是否,我们返回的是字符串,在 SpringMVC 内部会调用StringHttpMessageConverter的方法转换,而这里StringHttpMessageConverter设置的编码格式为Charset.forName("ISO-8859-1")[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nSXTeUMB-1602078341165)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/12.jpg)]

    5.2 配置 MessageConverter

    这里我们打开WebAppConfig配置类,它继承的WebMvcConfigurerAdapter有一个空方法

    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { }

    我们需要注册一个StringHttpMessageConverter转换策略

    @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 配置 String 转换编码格式为 UTF-8 converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8"))); }

    这里我们在测试一次:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TGJzzbce-1602078341166)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/13.jpg)]

    看到这个结果,是不是很开心,让我再来测试一下上传过程,作为是否会乱码???

    5.3 测试请求体中文乱码

    这里再写一个方法,处理接收的请求体

    // 测试链接:http://localhost:8080/user-info?name="王五"&age=30&gender="男" @RequestMapping("/user-info") public String getUser(User user, Model model) { System.out.println(user); // 将数据放到 request 域 model.addAttribute("user",user); return "/user.jsp"; }

    我们来看控制台的打印,可以看到中文没有出现乱码【在Tomcat 8以后,服务器默认的编码格式就是 UTF-8,因此request请求不会出现乱码的现象了】

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lmd0ORvC-1602078341168)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/14.jpg)]

    六、视图解析、返回 JSON 数据和解决静态资源访问配置

    6.1 视图解析器

    一般我们返回视图的是否,不建议使用xxx.jsp的路径作为返回参数,这是我们通常会在web.xml配置视图解析器。

    <!--视图解析器--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"></property> <property name="suffix" value=".jsp"></property> </bean>

    然而,在全注解的SpringMVC中,我们只需要来到我们的WebAppconfig配置类,重写父类WebMvcConfigurerAdapter的方法void configureViewResolvers(...),来配置视图解析

    @Override public void configureViewResolvers(ViewResolverRegistry registry) { // 向容器注册了一个 InternalResourceViewResolver 视图解析器 registry.jsp("/WEB-INF/view/",".jsp"); } /* // 这是上面注册视图解析的底层代码实现,可以看到底层会给我们创建一个InternalResourceViewResolver, //并指定我们的视图前缀和后缀 public UrlBasedViewResolverRegistration jsp() { return this.jsp("/WEB-INF/", ".jsp"); } public UrlBasedViewResolverRegistration jsp(String prefix, String suffix) { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix(prefix); resolver.setSuffix(suffix); this.viewResolvers.add(resolver); return new UrlBasedViewResolverRegistration(resolver); } */

    启动Tomcat测试视图解析器是否生效[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VoWeGiDU-1602078341169)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/15.jpg)]

    访问的地址:/WEB-INF/view/user.jsp.jsp

    返回的地址:return "/user.jsp";

    可以看出视图解析器已经生效了,我们需要修改返回的地址,并将视图放到/WEB-INF/view/目录即可

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vGEFCwq4-1602078341170)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/16.jpg)]

    6.2 返回 JSON 数据

    对于一个Web应用,返回 JSON 数据应该是必要的功能,我们测试一下 SpringMVC 是否可以返回 JSON 数据

    // 返回任意对象并转换成JSON对象 @RequestMapping("/all-users") @ResponseBody public Object getAllUsers() { List<User> userList = service.getAllUsers(); return userList; }

    当我们访问该地址时我们可以看到如下结果:

    java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.ArrayList

    这是因为我们没有jackson-databind的依赖,在转换成 json 数据时,会执行MappingJackson2HttpMessageConverter,而该类型需要jackson-databind的支持,我们需要导入它的依赖

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

    并且将MappingJackson2HttpMessageConverter重新注册到容器中;我们还是需要来到WebAppConfig配置类,在void configureMessageConverters(...)完成消息转换的注册

    @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 向容器注册一个 MappingJackson2HttpMessageConverter 实例 converters.add(new MappingJackson2HttpMessageConverter(new ObjectMapper())); }

    这样我们就可以解析对象为 json数据了[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6E7mJqxA-1602078341171)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/18.jpg)]

    6.3 解决静态资源访问问题

    在spring-mvc.xml配置中,我们需要使用以下配置解决静态资源访问问题

    <mvc:default-servlet-handler/>

    而在全注解配置里面,我们需要在WebAppconfig配置文件完成上面配置。

    同样我们需要重写WebMvcConfigurerAdapter的void configureDefaultServletHandling(...)方法,开启即可。

    @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); }

    七、SpringMVC 集成 Mybatis

    7.1 环境搭建

    7.1.1 导入Maven依赖

    <!--Spring 操作数据库的一些依赖和控制事务--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.20.RELEASE</version> </dependency> <!--mybatis和spring的整合依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!--mysql驱动【需要和本地的数据库版本一致】--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> <!--alibaba druid数据库连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>

    7.1.2 建立测试数据库和表

    drop database TestSpringMVC; create database TestSpringMVC; use TestSpringMVC; create table tbl_user( id int auto_increment primary key , name varchar(32), age int, birthday datetime ); insert into tbl_user(name, age, birthday) values ('张三',30,'1999-08-09'),('李四',22,'1998-03-09'), ('王五',20,'1987-08-19'),('余阳',21,'1999-08-03');

    7.1.3 编写 db.properties

    jdbc.driverClassName=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/TestSpringMVC?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8 jdbc.username=root jdbc.password=1234

    7.1.4 编写测试Dao接口

    接口:

    @Repository public interface IUserDao { User selectUserById(int id); List<User> selectAllUsers(); int insertUser(User user); }

    Mybatis的 IUserDao.xml文件:

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.shph.dao.IUserDao"> <sql id="user_column"> id, name, age,gender, birthday </sql> <!--根据 id 查询--> <select id="selectUserById" parameterType="int" resultType="User"> select <include refid="user_column"></include> from tbl_user where id=#{arg0}; </select> <!--查询所有用户--> <select id="selectAllUsers" resultType="User"> select <include refid="user_column"></include> from tbl_user </select> <!--插入数据,并返回自增主键回填到 User对象--> <insert id="insertUser" parameterType="User"> <selectKey keyProperty="id" resultType="int" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> insert into tbl_user(name,age,gender,birthday) values (#{name},#{age},#{gender},#{birthday}) </insert> </mapper>

    7.1.5 解决 XXXMapper.xml 编译问题

    在IDEA工具中,位于 java 文件夹下的必须是 java 文件,否则不能编译,我们需要到 pom.xml 里面配置如下内容来解决。

    <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>com/shph/dao/**/*.xml</include> </includes> </resource> </resources> </build>

    7.2 组件注册和事务控制配置

    这里我们需要注册的组件主要有:

    DataSource【数据源】

    SqlSessionFactoryBean【这是Mybatis整合Spring提供的一个Bean用于mybatis的环境配置,这样就不需要添加mybatis-config.xml配置文件了】

    MapperScannerConfigurer【这个也是Mybatis整合Spring封装的一个配置类,用于Mapper相关的配置,如指定Mapper所在的位置,指定SqlSession】

    DataSourceTransactionManager【关于事务相关的配置】

    有关整合Mybatis的组件组成配置我们应该在Spring的配置类完成,因此我们需要在RootConfig配置类完成相关配置:

    // 开启事务控制 @EnableTransactionManagement // 将 db.properties 的配置导入到 Spring 的环境里面 @PropertySource(value = "classpath:db.properties") @Configuration @ComponentScan(basePackages = "com.shph", excludeFilters = @ComponentScan.Filter({Controller.class})) public class RootConfig { // 配置数据库连接池 @Bean(value = "dataSource", initMethod = "init", destroyMethod = "close") public DruidDataSource initDruidDataSource( @Value("${jdbc.driverClassName}") String driverClassName, @Value("${jdbc.url}") String url, @Value("${jdbc.username}") String username, @Value("${jdbc.password}") String password ) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClassName); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } // 初始化 SqlSessionFactoryBean @Bean("sqlSessionFactory") public SqlSessionFactoryBean initSqlSessionFactoryBean(DataSource dataSource) throws IOException { SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); sqlSessionFactory.setDataSource(dataSource); PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); sqlSessionFactory.setMapperLocations(resolver.getResources("classpath:com/shph/dao/*.xml")); sqlSessionFactory.setTypeAliasesPackage("com.shph.entity"); return sqlSessionFactory; } @Bean public MapperScannerConfigurer initMapperScannerConfigurer() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage("com.shph.dao"); // 这里的 sqlSessionFactory 字符串必须与注册 SqlSessionFactoryBean 时指定的 id 值一样 configurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); return configurer; } // 配置事务管理 @Bean public DataSourceTransactionManager transactionManager(DataSource dataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); return transactionManager; } }

    【注意:这里有一个小问题,在DataSource数据源配置时,使用 @Value注解从Spring的环境去配置信息可能会失效,关于失效原因这里可以参考该文档:@Value不能注入解决方案】

    7.3 Mybatis 日志打印

    关于日志配置在Mybatis官网有介绍环境配置https://mybatis.org/mybatis-3/zh/logging.html,这里就简单概述一些。

    在Mybatis官方推荐我们使用 log4j 日志框架,因此我们这里就介绍一些 log4j 的配置。

    7.3.1 导入 log4j 依赖

    <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>

    7.3.2 编写 log4j 配置文件log4j.properties

    这里需要关注一些 log4j 的日志打印级别OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL,如果我们想要看到 mysql 的sql语句执行输出日志,日志级别需要 DEBUG及以下

    # 全局日志配置 log4j.rootLogger=DEBUG, stdout # MyBatis 日志配置 log4j.logger.org.mybatis.example.BlogMapper=TRACE # 控制台输出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

    7.4 测试Mybatis的集成

    7.4.1 测试查询所有

    URL地址:http://localhost:8080/all-users

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VcsFApx1-1602078341173)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/19.jpg)]

    7.4.2 测试通过 id 查询用户

    URL地址:http://localhost:8080/user?id=1

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QBmIPcjA-1602078341174)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/20.jpg)]

    7.4.3 测试插入一条用户数据

    这里编写了一个简单的 jsp页面,用于提交用户信息

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PtcSlY7N-1602078341175)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/21.jpg)]

    URL地址:http://localhost:8080/add-user?name=翠芬&age=19&gender=女&birthday=2000-02-09

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g3eihR0Y-1602078341177)(https://shphuang_aliyun.gitee.io/pictures-of-the-warehouse/spring-mvc-annotation-all-demo-img/22.jpg)]

    这是由于在提交的数据里面有一个日期birthday=2000-02-09数据,在后端接收数据时需要转换成Date对象类型,但是2000-02-09是字符串,无法转换成日期类型。

    解决方案一:

    在Spring的org.springframework.format.annotation.DateTimeFormat提供了一个注解,用于格式化日期,在属性或者set方法上添加该注解即可解决。

    @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birthday;

    解决方案二:参考文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web.html#mvc-config-conversion

    我们需要编写一个实现类实现接口Converter,该接口有一个方法,用于数据转换

    public class StringToDateConvert implements Converter<String, Date> { @Override public Date convert(String source) { if (!Pattern.matches("^\\d{4}-\\d{2}-\\d{2}$",source)) { return null; } SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = null; try { date = dateFormat.parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; } }

    同时,我们还需要去注册到 Formatter 转换器才能使用:

    来到配置类WebAppConfig重写其父类方法void addFormatters(...)

    // 注册 Formatter 转换器 @Override public void addFormatters(FormatterRegistry registry) { // 将自定义字符串日期转换器添加到 FormatterRegistry registry.addConverter(new StringToDateConvert()); }

    nverter<String, Date> { @Override public Date convert(String source) { if (!Pattern.matches("^\d{4}-\d{2}-\d{2}$",source)) { return null; }

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = null; try { date = dateFormat.parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; }

    }

    同时,我们还需要去注册到 Formatter 转换器才能使用: 来到配置类`WebAppConfig`重写其父类方法`void addFormatters(...) ` ```java // 注册 Formatter 转换器 @Override public void addFormatters(FormatterRegistry registry) { // 将自定义字符串日期转换器添加到 FormatterRegistry registry.addConverter(new StringToDateConvert()); }

    后期作者可能不定时更新…

    Processed: 0.011, SQL: 8