SpringMVC全注解环境搭建

源代码:

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

一、基本环境

  1. jdk 1.8
  2. IDEA 2019
  3. Maven 3.6.3
  4. Tomcat 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配置文件完成上面配置。

同样我们需要重写WebMvcConfigurerAdaptervoid 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 组件注册和事务控制配置

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

  1. DataSource【数据源】

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

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

  4. 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());
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值