IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Web项目实战 | 购物系统v2.0 | 开发记录(二)搭建SpringBoot+SSM框架环境 | 配置Druid+MyBatis | 基于Bootstrap实现登陆页面| 图片验证码接口 -> 正文阅读

[Java知识库]Web项目实战 | 购物系统v2.0 | 开发记录(二)搭建SpringBoot+SSM框架环境 | 配置Druid+MyBatis | 基于Bootstrap实现登陆页面| 图片验证码接口

历史记录

Web项目实战 | 购物系统v2.0 | 开发记录(一)需求分析 | 技术选型 | 系统设计 | 数据表设计 | SpringBoot、SSM、Thymeleaf、Bootstrap…

Web项目实战 | 购物系统v2.0 | 开发记录(二)

一、运行环境


  • windows10
  • IDEA 2021.1 专业版
  • JDK8
  • SpringBoot2
  • Druid 1.2.5
  • Bootstrap 4.6.0
  • MySQL 8
  • Navicat 11

二、环境准备


创建 SpringBoot项目,导入相关的起步依赖、配置Druid数据源,测试数据库连接

2.1 使用 IDEA 创建SpringBoot项目

第一步,新建项目
在这里插入图片描述

第二步,选择需要引入的依赖,这里不选全也没事,本质上就是在pom.xml添加相关starter起步依赖,后续还可以添加其他的起步依赖
在这里插入图片描述
第三步,了解项目结构
在这里插入图片描述
SpringBoot的配置文件都必须命名为application,不过它具有三种不同的格式,有properties、yaml、yml,这里笔者使用yml格式,因为看起来整洁许多,如果同时都有配置的话,是有一个优先级的,在同一级目录下优先级(高 -> 低)为 properties -> yml -> yaml
[相关内容的笔记链接]

2.2 导入所需依赖

除了之前选择的Web、Thymeleafr、Lombok以外,还要确保有mysql、autoconfigure等依赖,具体配置如下:
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.uni</groupId>
    <artifactId>simple-shop-system-v2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>simple-shop-system-v2</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.5.6</version>
        </dependency>

  
        <!-- Bootstrap -->
        <!-- https://mvnrepository.com/artifact/org.webjars/bootstrap -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.6.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2.3 配置Druid数据源

在pom.xml里添加相同依赖:
pom.xml

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>

application.yml

spring:
  datasource:
    username: root
    password: 数据库密码
    url: jdbc:mysql://localhost:3306/simple_shop_system_2?useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

2.4 编写Java类配置Druid

其实在导入Druid起步依赖后,它会有默认的配置注入到Spring容器的,其原理就是通过Java类进行配置,观察jar包里的源码内容:
在这里插入图片描述

其源码是通过注解进行配置的,而我们在配置时只需要@Configuration注解表示当前类是一个配置类就行,通过源码可以看到,其作者(来自阿里的大佬)留下了他的QQ号~

在配置Druid时需注意,需要配置哪个对象就使用该对象定义一个方法,同时用@Bean注解标记该方法,这样SpringBoot可以将方法返回的结果注入到Spring容器,即完成配置

DruidConfig.java

package com.uni.config;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DruidConfig {
    //配置Druid监控管理后台的servlet
    //内置Servlet容器时没有web.xml文件,所以使用springboot的注册servlet的方式
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        //这些参数可以在com.alibaba.druid.support.http.StatViewServlet的父类com.alibaba.druid.support.http.ResourceServlet 中找到
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");//后台管理界面的登录账号
        initParams.put("loginPassword","123456");//后台管理界面的登录密码
        //allow: Druid后台白名单
        initParams.put("allow","127.0.0.1");//为空或者为null时,表示允许所有访问
        //deny: Druid后台黑名单
        initParams.put("dz","192.168.1.66");//表示禁止此ip访问
        //设置初始化参数
        bean.setInitParameters(initParams);
        return bean;
    }
    //配置Druid监控之Web监控的filter
    //webStatFiler:用于配置web和Druid数据源之间的管理关联监控统计
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        //exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*,/jdbc/*");
        //"/*" 表示过滤所有请求
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}

2.5 测试Druid

方式一: 启动SpringBoot项目,访问Druid后台

最简单粗暴的方法就是直接启动项目,访问Druid后台,地址为:https://localhost:8080/duird/login.html,登陆账号和密码就是之前Config类里配置的
在这里插入图片描述

方式二: 使用Junit单元测试编写测试方法,DataSource 对象是从Spring容器获取的,因为SpringBoot会将它注入到容器中,最后运行没报错就行!

@Autowired
DataSource dataSource;
@Test
void testDruid() throws SQLException {
    //看一下默认数据源
    System.out.println(dataSource.getClass());
    //获取连接
    Connection connection = dataSource.getConnection();
    System.out.println(connection);

    DruidDataSource druidDataSource = (DruidDataSource) dataSource;
    System.out.println("druidDataSource 数据源最大连接数"+druidDataSource.getMaxActive());
    System.out.println("druidDataSource 数据源初始化连接数"+druidDataSource.getInitialSize());
    //关闭连接
    connection.close();
}

在这里插入图片描述

三、MyBatis 逆向工程


根据上次的笔记,MyBatis逆向工程,本次项目开发可以使用这个功能,而无需每次都重新写CRUD,实现逆向工程的方法有多种,常见的有XML配置 + Maven插件 ,XML 配置 + Java类反向代理,这里笔者选择Maven插件。

SpringBoot整合MyBatis逆向工程

3.1 导入所需依赖

pom.xml

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
	<dependency>
	    <groupId>org.mybatis.spring.boot</groupId>
	    <artifactId>mybatis-spring-boot-starter</artifactId>
	    <version>2.2.1</version>
	</dependency>
	<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-autoconfigure</artifactId>
	    <version>2.5.6</version>
	</dependency>
	
	<!-- MyBatis 逆向工程 -->
	<dependency>
	    <groupId>org.mybatis.generator</groupId>
	    <artifactId>mybatis-generator-core</artifactId>
	    <version>1.3.5</version>
	</dependency>
</dependencies>

<build>
       <plugins>
           <!-- 支持 MyBatis 逆向工程的 Maven插件 -->
           <plugin>
               <groupId>org.mybatis.generator</groupId>
               <artifactId>mybatis-generator-maven-plugin</artifactId>
               <version>1.3.6</version>
               <dependencies>
                   <dependency>
                       <groupId>mysql</groupId>
                       <artifactId>mysql-connector-java</artifactId>
                       <version>8.0.25</version>
                   </dependency>
               </dependencies>
               <configuration>
                   <!--配置文件的位置-->
                   <configurationFile>src/main/resources/mybatis/generatorConfig.xml</configurationFile>
                   <verbose>true</verbose>
                   <overwrite>true</overwrite>
               </configuration>
           </plugin>
       </plugins>
   </build>

3.2 逆向工程配置

generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!-- context 运行上下文 -->
    <!-- id 必唯一 -->
    <!-- defaultModelType:可选;flat:所有内容(主键,blob)等全部生成在一个对象中 -->
    <!-- targetRuntime:可选 ;建议:MyBatis3Simple/MyBatis3 -->
    <context id="MySqlTables" defaultModelType="flat"
             targetRuntime="MyBatis3">

        <!--beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号 -->
        <!--如ORACLE就是双引号;MYSQL默认是`反引号; -->
        <property name="beginningDelimiter" value="`" />
        <property name="endingDelimiter" value="`" />

        <!-- 指定生成的java文件的编码,没有直接生成到项目时中文可能会乱码 -->
        <property name="javaFileEncoding" value="UTF-8" />

        <!-- 格式化java代码 -->
        <property name="javaFormatter"
                  value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />

        <!-- 格式化XML代码 -->
        <property name="xmlFormatter"
                  value="org.mybatis.generator.api.dom.DefaultXmlFormatter" />

        <!--自动实现Serializable可序列化接口 -->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />

        <!--去除生成的注释;建议初次不去注释 -->
        <commentGenerator>
            <!-- 去除自动生成时的时间戳 -->
            <property name="suppressDate" value="true" />
            <!-- 去除自动生成的注释 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!--数据库基本信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/simple_shop_system_2?characterEncoding=UTF-8"
                        userId="root"
                        password="数据库密码">
        </jdbcConnection>

        <!-- java类型处理器 用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl; -->
        <!-- 注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和 NUMERIC数据类型; -->
        <javaTypeResolver
                type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
            <!-- true:使用BigDecimal对应DECIMAL和 NUMERIC数据类型 -->
            <!--false:默认, -->
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!--Java model(POJO)生成的位置 -->
        <!--targetPackage:包路径 -->
        <!--targetProject:项目路径 -->
        <javaModelGenerator targetPackage="com.uni.pojo"
                            targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!--*Mapper.xml生成的位置 -->
        <sqlMapGenerator targetPackage="mybatis.mapper"
                         targetProject="src/main/resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 -->
        <!--type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下) -->
        <!--1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML -->
        <!--2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中 -->
        <!--3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML -->
        <!--注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.uni.dao" targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!--表的名称;对应类的名称; -->
        <table tableName="uni_commodity" domainObjectName="Commodity">
            <property name="useActualColumnNames" value="true"/>
        </table>
        <table tableName="uni_commoditytype" domainObjectName="CommodityType">
            <property name="useActualColumnNames" value="true"/>
        </table>
        <table tableName="uni_order" domainObjectName="Order">
            <property name="useActualColumnNames" value="true"/>
        </table>
        <table tableName="uni_provider" domainObjectName="Provider">
            <property name="useActualColumnNames" value="true"/>
        </table>
        <table tableName="uni_role" domainObjectName="Role">
            <property name="useActualColumnNames" value="true"/>
        </table>
        <table tableName="uni_user" domainObjectName="User">
            <property name="useActualColumnNames" value="true"/>
        </table>
    </context>
</generatorConfiguration>

3.3 运行Maven插件启动逆向工程

在这里插入图片描述

3.4 问题与优化

由逆向工程生成的Mapper结果提供了许多CRUD的方法,比如在用户接口里
UserMapper.java

package com.uni.dao;

import com.uni.pojo.User;
import com.uni.pojo.UserExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;

public interface UserMapper {
    long countByExample(UserExample example);

    int deleteByExample(UserExample example);

    int deleteByPrimaryKey(Long id);

    int insert(User record);

    int insertSelective(User record);

    List<User> selectByExample(UserExample example);

    User selectByPrimaryKey(Long id);

    int updateByExampleSelective(@Param("record") User record, @Param("example") UserExample example);

    int updateByExample(@Param("record") User record, @Param("example") UserExample example);

    int updateByPrimaryKeySelective(User record);

    int updateByPrimaryKey(User record);
}
}

上述是默认生成的Mapper接口类,在使用时只需要声明接口,并使用`@Autowired从Spring的IoC容器获取对应的Bean就可以调用相关方法,由于是第二次使用,关于逆向工程还有一些潜在的小问题,现进行一个总结:

问题1: 自动生成的pojo实体类没有toString()方法

  • 解决方式:使用lombok的@Data注解自动生成toString方法,同时删去不必要的setter、getter方法,因为lombok可以自动生成这样的方法。不过有些set、get是对字段有特殊处理的,就不需要删,比如修改后的用户pojo类如下:

User.java

package com.uni.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;
@Data
@NoArgsConstructor
public class User implements Serializable {
    
    private Long id;
    private String userCode;
    private String userName;
    private String userPassword;
    private Integer gender;
    private Date birthday;
    private String phone;
    private String address;
    private Long createBy;
    private Date createionDate;
    private Long modifyBy;
    private Date modifyDate;
    private String pwd;
    private String salt;
    private Integer userRole;
    private String userImgSrc;

    private static final long serialVersionUID = 1L;
    public void setUserCode(String userCode) {
        this.userCode = userCode == null ? null : userCode.trim();
    }
    public void setUserName(String userName) {
        this.userName = userName == null ? null : userName.trim();
    }
    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword == null ? null : userPassword.trim();
    }
    public void setPhone(String phone) {
        this.phone = phone == null ? null : phone.trim();
    }
    public void setAddress(String address) {
        this.address = address == null ? null : address.trim();
    }
    public void setPwd(String pwd) {
        this.pwd = pwd == null ? null : pwd.trim();
    }
    public void setSalt(String salt) {
        this.salt = salt == null ? null : salt.trim();
    }
    public void setUserImgSrc(String userImgSrc) {
        this.userImgSrc = userImgSrc == null ? null : userImgSrc.trim();
    }
}

问题2: SpringBoot如何整合这些Mapper接口

  • 解决方法:和之前Spring整合MyBatis类似,先进行DAO层接口扫描的配置,这样就能通过注解@Component将DAO层的类注入到Spring容器。

(1)MyBatis配置文件和SQL映射文件的配置
application.yml

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

在这里插入图片描述
(2)配置支持扫描Mapper接口的包,这个在SpringBoot启动类中配置,使用@MapperScan(value = "包名")注解即可

package com.uni;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(value = "com.uni.dao")
public class SimpleShopSystemV2Application {

    public static void main(String[] args) {
        SpringApplication.run(SimpleShopSystemV2Application.class, args);
    }
}

(3)在Mapper接口类里使用注解@Component注入到Spring容器
在这里插入图片描述
问题3: 如何测试逆向工程的Mapper接口

  • 解决方法:按照之前MVC的设计结构,Mapper接口应当在Service层使用,现在通过Junit单元测试进行简单的测试,看看是否能从Spring容器中获取的Bean是否能正常执行相关方法
@Autowired
RoleMapper roleMapper;
@Test
public void TestMyBatisGenerator(){
    roleMapper.selectByExample(new RoleExample()).forEach(
            role -> System.out.println(role)
    );
}

运行结果如下:
在这里插入图片描述
至此,MyBatis逆向工程 、项目的MyBatis环境设置完毕

四、实现登陆页面


通过Bootstrap4框架实现,验证码使用了现成的接口,接下来会详细说明
在这里插入图片描述

4.1 导入所需依赖

pom.xml

<dependency>
     <groupId>org.webjars</groupId>
     <artifactId>bootstrap</artifactId>
     <version>4.6.0</version>
 </dependency>

 <dependency>
     <groupId>org.webjars.npm</groupId>
     <artifactId>bootstrap-icons</artifactId>
     <version>1.7.2</version>
 </dependency>

 <dependency>
     <groupId>org.webjars</groupId>
     <artifactId>jquery</artifactId>
     <version>3.3.1</version>
 </dependency>

4.2 实现代码

HTML部分代码:这里是通过Thymeleaf引擎渲染页面,负责前后端交互,是SpringBoot官方支持的引擎,通过各种th标签可以获取到Controller层传输的数据。这里导入资源的方式是webjar, 即之前导入的Jar包依赖,是通过Maven工程的GAV坐标定位资源文件的。

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>登录页面</title>
    <!-- Bootstrap core CSS -->
    <link th:href="@{/webjars/bootstrap/4.6.0/css/bootstrap.css}" rel="stylesheet">
    <link th:href="@{/webjars/bootstrap-icons/1.7.2/font/bootstrap-icons.css}" rel="stylesheet">
</head>
<body>
	<!-- ... -->
<script type="text/javascript" th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
</body>

4.3 判断用户是否存在+获取用户头像

为了更友好的提示用户,当用户离开账号的输入框时候,输入框会做出反馈,若存在则成呈现为绿色,否则就呈现为红色,这个可以通过 Boostrap4框架提供的CSS类来实现,即 is-validis-invalid

  <script>
        /* 用户名检验 */
        var check_usercode = true
        /* 密码检验 */
        var check_password = true
        /* 登陆 */
        $("#form-usercode").blur(function (){
            let userCode = $(this).val()
            if (userCode != '') {

                /* 检查账号是否存在 */
                $.ajax({
                    url: '/login/' + userCode,
                    type: 'GET',
                    async: false,
                    error: (err) => {
                        alert('AJAX请求失败!')
                        console.log(err.status)
                        console.log(err.responseText)
                    },
                    success: (result) => {
                        if (result == 'true') {
                            check_usercode = true
                            $("#form-usercode").removeClass('is-invalid')
                            $("#form-usercode").addClass('is-valid')
                        } else {
                            check_usercode = false
                            $("#form-usercode").removeClass('is-valid')
                            $("#form-usercode").addClass('is-invalid')
                        }
                    }
                })
            } else {
                check_usercode = false
                $("#form-usercode").removeClass('is-valid')
                $("#form-usercode").addClass('is-invalid')
            }
            /* 若账号存在则查找身份 */
            if(check_usercode){
                $.ajax({
                    url: '/imgSrc/' + userCode,
                    type: 'GET',
                    async: false,
                    dataType: 'text',
                    error: (err) => {
                        alert('查找身份AJAX请求失败!')
                        console.log(err.responseText)
                    },
                    success: (imgSrc) => {
                        $('.card-img-top').attr('src', imgSrc)
                    }
                })
            } else $('.card-img-top').attr('src', '/images/user_common.png')
        });
        $("#btn-login").click({
				//... 待实现
        })
    </script>

Controller层:
UserAction.java

@Autowired
private UserService userService;
@GetMapping("/login/{userCode}")
@ResponseBody
public String checkUserCode(@PathVariable String userCode){
        return userService.checkUserCode(userCode) ? "true" : "false";
}
@GetMapping("/imgSrc")
@ResponseBody
public String defaultImgSrc(){
    return "/images/user_common.png";
}
@GetMapping("/imgSrc/{userCode}")
@ResponseBody
public String selectImgSrc(@PathVariable String userCode){
    String imgSrc = userService.getImgSrc(userCode);
    return imgSrc;
}

Service层

@Autowired
UserMapper userMapper;
@Override
public Boolean checkUserCode(String userCode) {
    UserExample example = new UserExample();
    UserExample.Criteria criteria = example.createCriteria();
    criteria.andUserCodeEqualTo(userCode);
    return userMapper.selectByExample(example).size() == 1;
}

@Override
public String getImgSrc(String userCode) {
    List<User> users = userMapper.selectByExample(new UserExample() {{
        Criteria criteria = createCriteria();
        criteria.andUserCodeEqualTo(userCode);
    }});
    return users != null && users.size() == 1? users.get(0).getUserImgSrc() : null;
}

4.4 通过类配置web首页

通过实现WebMvcConfigurer接口,再通过@Configuration注入到Spring容器这种方式可以得SpringMVC进行配置,比如可以将 "/"的请求转发到地址为"login"的视图,后缀默认为html

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
    }
}

4.5 图片验证码接口 Captcha

作者:Hansin1997

项目地址:https://gitee.com/hansin/captcha(已star)

笔者是根据这位大神提供的开发文档实现的图片验证码,总共有以下四步。

第一步,导入依赖
pom.xml

<dependency>
    <groupId>cn.dustlight.captcha</groupId>
    <artifactId>captcha-core</artifactId>
    <version>1.0.1</version>
</dependency>

第二步,在SpringBoot启动类中使用注解@EnableCaptchacaptcha使能

package com.uni;

import cn.dustlight.captcha.annotations.EnableCaptcha;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(value = "com.uni.dao")
@EnableCaptcha
public class SimpleShopSystemV2Application {

    public static void main(String[] args) {
        SpringApplication.run(SimpleShopSystemV2Application.class, args);
    }
}

第三步,在Controller层编写业务逻辑

package com.uni.controller;

import cn.dustlight.captcha.annotations.CodeValue;
import cn.dustlight.captcha.annotations.SendCode;
import cn.dustlight.captcha.annotations.VerifyCode;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/* 来自 https://gitee.com/hansin/captcha */
@RestController
public class CodeAction {
    /**
     * 获取验证码。
     * 注解 '@SendCode' 表示此方法执行之前将生成验证码并进行发送。
     *
     * @param code 生成的验证码,通过注解 '@CodeValue' 传入
     */
    @RequestMapping("/captcha")
    @SendCode
    public void captcha(@CodeValue String code) {
        // 在此处进行自定义的业务,验证码的生成、发送与储存已由注解 '@SendCode' 完成。
        return ;
    }

    /**
     * 消费验证码
     * 注解 '@VerifyCode' 表示此方法执行之前先进行验证码验证。
     *
     * @param code 参数中的验证码,通过注解 '@CodeValue' 表示此参数为需要被验证的参数。
     * @return
     */
    @RequestMapping("/code")
    @VerifyCode
    public String index(@CodeValue String code) {
        // 在此处进行自定义的业务,验证码的验证以及销毁已由注解 '@VerifyCode' 完成。
        return String.format("Hello World! (%s)", code);
    }
}

第四步,在HTML中的图片里指定src到Controller层对应的地址

<img th:src="@{/captcha}" style="width: 60px; height: 34px">

五、Bug & DeBug


使用MyBatis逆向工程后,User表识别错误,识别到了MySQL自带的User用户表

解决:修改表名,所有表加上前缀uni_,然后重新启动Maven插件,逆向生成DAO层接口和SQL映射文件

MyBatsi逆向工程生成的POJO类属性全是小写的,在配置时需在table标签里添加<property name="useActualColumnNames" value="true"/>,用于指定当前表遵循驼峰命名规则

Thymeleaf图片没有正常显示

<img th:src="@{/static/images/user_common.png}" class="img-circle" width="100px" height="100px">

解决:去掉/static

六、总结


今天花时间最多的还是在前端设计上,看来很有必要整一套适合自己的页面设计,不然每次都花时间去调样式,太不合理,通过本次开发,更加熟悉了SpringBoot的注解配置,其作用和XML是类似的,需要配置的时候查资料就行,其次是MyBatis逆向工程真的很方便,今天虽然还没真正实现登陆的需求,但是能感觉到根本不需要写SQL语句,直接用生成的方法来调用Mapper接口,比以前一个一个的去写SQL语句方便多了…

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 22:56:59  更:2022-01-29 22:58:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:58:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码