手把手教你整合SSM实现一个简单的CRUD项目

项目笔记

一.项目简介

这是一个基于SSM框架的简单CRUD(Create Retrieve Update Delete)网页的项目,使用的IDE是IDEA2021.1。
由于篇以及时间问题,本篇暂先介绍前两部分,项目中容易遇到的问题及解决方法将在之后的文章给出。具体项目地址:https://gitee.com/qc-sxt/userSystem-SSM

二.项目步骤

1.搭建数据库环境

首先创建项目需要的数据库,取名就为db3,内含两个表:一个是用户表,用于显示用户信息;一个是管理员表,用于记录管理员的用户名和密码。最终实现只有管理员可以登录系统对用户的信息进行增删改查的目标。

CREATE TABLE IF NOT EXISTS administrator(  -- 创建administrator表
	id INT PRIMARY KEY AUTO_INCREMENT,  -- 管理员id,设置为主键且自动增长
	username VARCHAR(30),  -- 管理员用户名
	PASSWORD VARCHAR(30)  -- 管理员密码
);
-- 插入管理员数据
INSERT INTO administrator VALUES(NULL,"administrator1","888888");
INSERT INTO administrator VALUES(NULL,"administrator2","888888");

CREATE TABLE IF NOT EXISTS USER(  -- 创建用户表
	id INT PRIMARY KEY AUTO_INCREMENT,  -- 用户id,设置为主键且自动增长
	NAME VARCHAR(30) NOT NULL,  -- 用户姓名,非空
	gender VARCHAR(10),  -- 用户性别
	age INT,  -- 用户年龄
	address VARCHAR(20),  -- 用户地址
	qq VARCHAR(30),  -- 用户QQ号
	email VARCHAR(30)  -- 用户邮箱
);
-- 插入用户数据
INSERT INTO USER VALUES(NULL,"张三","男",25,"北京","123456","[email protected]");
INSERT INTO USER VALUES(NULL,"李四","女",20,"上海","456789","[email protected]");
INSERT INTO USER VALUES(NULL,"王五","男",28,"广州","123456","[email protected]");
INSERT INTO USER VALUES(NULL,"赵六","女",23,"深圳","456789","[email protected]");

执行完毕sql后查看一下表以及表中的数据是否有问题,没问题的话数据库便建好了。

2.dao层编写(基于mybatis框架)

(1)在IDEA中新建一个基于Maven管理的空项目,命名为userSystem_SSM。在项目的pom.xml文件中引入依赖并设置资源过滤(防止之后编写的xml、properties配置文件无法被找到)。pom.xml编写好之后记得刷新一下Maven。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sxt</groupId>
    <artifactId>userSystem_SSM</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <!--这里是只用了mybatis框架情况下的依赖,之后整合了spring和springmvc框架后会继续修改这个配置文件 -->
    
    <dependencies>
        <!--mybatis环境-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!--mysql环境-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>
        <!--单元测试junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!--日志输出log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <!--开启资源过滤-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>

</project>

(2)在Java目录下新建包:com.sxt.pojo(Plain Ordinary Java Object简单的Java对象,名字强调它是一个普通的java对象)、com.sxt.dao(Data Access Object数据访问对象,此对象用于访问数据库)、com.sxt.utils(工具包,里面放着整个项目的工具类)。

在pojo包下新建两个Java类:User(用户类)和Administrator(管理员类),分别对照数据库中的表编写其相应的属性以及getter和setter方法。构造函数在之后根据自己sql语句的需求生成,不过需注意:一旦生成了带参构造函数,默认的无参构造函数就必须显式声明出来。此处代码略过。

(3)在resources包下新建三个配置文件:database.properties、log4j.properties、mybatis-config.xml,分别用于数据库的配置、日志的配置以及mybatis核心配置文件。

# 数据库配置
driver=com.mysql.jdbc.Driver  # 数据库驱动
url=jdbc:mysql://localhost:3306/db3  # 数据库访问url
username=root  # 数据库用户名
password=root  # 数据库密码
# 全局日志配置
log4j.rootLogger=DEBUG,console
# MyBatis 日志配置
log4j.logger.com.example.dao.UserMapper=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

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
#log4j.appender.file = org.apache.log4j.RollingFileAppender
#log4j.appender.file.File=./log/sxt.log
#log4j.appender.file.MaxFileSize=10mb
#log4j.appender.file.Threshold=DEBUG
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
#SQL 语句将会在 DEBUG 日志级别下记录
#返回的结果集则会在 TRACE 日志级别下记录
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="database.properties"/>

    <typeAliases>
        <!--实体类少时使用-->
        <!--<typeAlias type="pers.sxt.pojo.User" alias="user"/>-->
        <!--实体类多时使用,默认别名为类名首字母小写-->
        <package name="com.sxt.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 每一个mapper.xml都需要在mybatis核心配置文件中注册! -->
    <mappers>
        <!--推荐使用,其他两种配置方式必须保证mapper接口和对应的xml映射配置文件在同一个包下,且接口类名和xml文件名必须保持一致-->
        <mapper resource="com/sxt/dao/UserMapper.xml"/>
        <!--<mapper class="com.example.dao.UserMapper"/>-->
        <!--<package name="com.example.dao"/>-->
    </mappers>
</configuration>

(4)在dao包下新建UserMapper接口和UserMapper.xml映射文件。

package com.sxt.dao;

import com.sxt.pojo.Administrator;
import com.sxt.pojo.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper {
    
    
    /**
     * 查询系统中的所有用户信息,返回用户对象的List集合
     * @return
     */
    List<User> findUsers();

    /**
     * 通过用户名和密码查询管理员信息,用于管理员登录
     * @Param是MyBatis所提供的,作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应,一般在2=<参数数<=5时使用最佳
     * 当只有一个参数时,没什么好说的,传进去一个值也只有一个参数可以匹配。
     * 当存在多个参数时,传进去的值就区分不开了,这时可以考虑用Map,也可以考虑用@Param注解(方便很多)
     * @param username
     * @param password
     * @return
     */
    Administrator findAdministrator(@Param("username") String username, @Param("password") String password);

    void addUser(User user);  //增加一个用户

    void deleteUser(int id);  //删除一个用户

    void deleteSelectedUsers(@Param("ids")int[] ids);  //批量删除选中用户

    void updateUser(User user);  //修改一个用户信息

    User findUserById(int id);  //根据id查询指定用户信息

}
<?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">
<!--namespace是必须属性,用来绑定一个对应的Mapper接口,此名称要和对应的xml文件名称一致-->
<mapper namespace="com.sxt.dao.UserMapper">
    <!--
        id:就是对应的namespace中的方法名
        resultType:sql语句执行的返回值,返回结果要写全限定名
        parameterType:参数类型
    -->
    <select id="findUsers" resultType="user">
        select * from user
    </select>

    <select id="findAdministrator" resultType="administrator">
        select * from administrator where username = #{username} and password = #{password}
    </select>

    <insert id="addUser" parameterType="user">
        insert into user values (#{id},#{name},#{gender},#{age},#{address},#{qq},#{email})
    </insert>

    <delete id="deleteUser" parameterType="_int">
        delete from user where id = #{id}
    </delete>

    <update id="updateUser" parameterType="user">
        update user set name=#{name},gender=#{gender},age=#{age},address=#{address},qq=#{qq},email=#{email} where id = #{id}
    </update>

    <delete id="deleteSelectedUsers" parameterType="int">
        delete from user where id in
        <!-- 动态sql语句值 foreach -->
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

    <select id="findUserById" resultType="user">
        select * from user where id = #{id}
    </select>

</mapper>

(5)在utils工具包下编写MyBatisUtils工具类

package com.sxt.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {
    
    
    private static SqlSessionFactory sqlSessionFactory;

    //每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。
    // SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
    // 而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例
    static {
    
    
        try {
    
    
            //使用mybatis第一步,获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法
    public static SqlSession getSqlSession(){
    
    
        return sqlSessionFactory.openSession();
    }
}

(6)编写测试类,测试dao层代码是否可以正常执行并输出正确的结果

package com.sxt.dao;

import com.sxt.pojo.Administrator;
import com.sxt.pojo.User;
import com.sxt.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class DaoTest {
    
    
    private static SqlSession sqlSession;
    private static UserMapper userMapper;

    static {
    
    
        sqlSession = MyBatisUtils.getSqlSession();
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void test1(){
    
    
        List<User> users = userMapper.findUsers();
        for (User user : users) {
    
    
            System.out.println(user);
        }
        sqlSession.close();
    }

    @Test
    public void test2(){
    
    
        Administrator administrator = userMapper.findAdministrator("administrator1","888888");
        System.out.println(administrator);
        sqlSession.close();
    }

    @Test
    public void test3(){
    
    
        User user = new User(5,"李四","男",50,"西安","123456","[email protected]");
        userMapper.addUser(user);
        sqlSession.commit();
        test1();
        sqlSession.close();
    }

    @Test
    public void test4(){
    
    
        userMapper.deleteUser(6);
        sqlSession.commit();
        test1();
        sqlSession.close();
    }

    @Test
    public void test5(){
    
    
        int[] ids = {
    
    5,6};
        userMapper.deleteSelectedUsers(ids);
        sqlSession.commit();
        test1();
        sqlSession.close();
    }

    @Test
    public void test6(){
    
    
        User user = new User(6,"张三","女",20,"成都","123456","[email protected]");
        userMapper.updateUser(user);
        sqlSession.commit();
        test1();
        sqlSession.close();
    }
}

至此,dao层的代码就编写完成了,已经可以实现基本的对数据的增删改查功能了。

3.service层编写(基于spring框架)

(1)在service包下新建一个UserService接口,实现业务操作(调用dao层对数据库进行操作)。

package com.sxt.service;

import com.sxt.pojo.Administrator;
import com.sxt.pojo.User;

import java.util.List;

//底下需要去实现,调用dao层。方法和UserMapper中的方法完全一致
public interface UserService {
    
    
    List<User> findUsers();

    Administrator findAdministrator(String username, String password);

    void addUser(User user);

    void deleteUser(int id);

    void deleteSelectedUsers(int[] ids);

    void updateUser(User user);

    User findUserById(int id);
}

(2)在service包下新建一个impl包,用于存放UserService接口的实现类。接着在UserServiceImpl包下新建一个UserServiceImpl类,编写具体的业务操作(都是调用dao层的接口调用其方法执行sql语句)

package com.sxt.service.impl;

import com.sxt.dao.UserMapper;
import com.sxt.pojo.Administrator;
import com.sxt.pojo.User;
import com.sxt.service.UserService;
import java.util.List;

public class UserServiceImpl implements UserService {
    
    

    //调用dao层的操作,设置一个set接口,方便Spring管理
    private UserMapper userMapper;
	//之后spring容器就可以通过属性注入userMapper对象
    public void setUserMapper(UserMapper userMapper) {
    
    
        this.userMapper = userMapper;
    }

    public List<User> findUsers() {
    
    
        return userMapper.findUsers();
    }

    public Administrator findAdministrator(String username, String password) {
    
    
        return userMapper.findAdministrator(username,password);
    }

    public void addUser(User user) {
    
    
        userMapper.addUser(user);
    }

    public void deleteUser(int id) {
    
    
        userMapper.deleteUser(id);
    }

    public void deleteSelectedUsers(int[] ids) {
    
    
        userMapper.deleteSelectedUsers(ids);
    }

    public void updateUser(User user) {
    
    
        userMapper.updateUser(user);
    }

    public User findUserById(int id) {
    
    
        return userMapper.findUserById(id);
    }
}

(3)整合mybatis和spring,需要用到mybatis-spring依赖(可以将 MyBatis 代码无缝地整合到 Spring 中)、spring-webmvc依赖(内含spring-beans,spring-context,spring-core等多个包,导这一个很方便)、spring-jdbc依赖(spring的事务管理)。因此修改pom.xml文件,在依赖项 中间加入如下配置,之后刷新一下Maven即可:

<!--spring环境-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>
<!--mybatis和spring整合包-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.2</version>
</dependency>

(4)编写spring整合mybatis的配置文件,即dao层交由spring管理。在resources文件夹下新建spring-dao.xml文件,编写配置:

注意:这里务必务必先去将数据库配置文件database.properties中的每个属性前加上jdbc.

即这个样子:否则可能会出现一些奇奇怪怪的问题,至于原因网上有很多,在此不再赘述

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db3
jdbc.username=root
jdbc.password=root

spring-dao.xml:

<?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"
       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">

    <!-- 关联数据库文件 -->
    <context:property-placeholder location="classpath:database.properties"/>

    <!--配置数据源:数据源有非常多,可以使用第三方的,也可使使用Spring的-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--配置SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--关联Mybatis-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--如果Mapper.xml与Mapper.class在同一个包下且同名,-->
        <!--spring扫描Mapper.class的同时会自动扫描同名的Mapper.xml并装配到Mapper.class。-->
        <!--如果Mapper.xml与Mapper.class不在同一个包下或者不同名,就必须使用配置mapperLocations指定mapper.xml的位置。-->
        <!--此时spring是通过识别mapper.xml中的 <mapper namespace="com.sxt.dao.UserMapper"> namespace的值来确定对应的Mapper.class的。-->
        <!--<property name="mapperLocations" value="classpath:com/sxt/dao/*.xml"/>-->
    </bean>

        <!--注册sqlSessionTemplate , 关联sqlSessionFactory-->
        <!--<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
            <!--利用构造器注入-->
            <!--<constructor-arg index="0" ref="sqlSessionFactory"/>-->
        <!--</bean>-->

    <!-- 配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 给出需要扫描Dao接口包 -->
        <property name="basePackage" value="com.sxt.dao"/>
    </bean>

</beans>

写好之后需要修改mybatis-config.xml文件,只保留其基础配置(通常,基础配置指的是 <settings><typeAliases> 元素)

改好之后的mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <typeAliases>
        <!--实体类少时使用-->
        <!--<typeAlias type="pers.sxt.pojo.User" alias="user"/>-->
        <!--实体类多时使用-->
        <package name="com.sxt.pojo"/>
    </typeAliases>
</configuration>

如果 MyBatis 在映射器类对应的路径下找不到与之相对应的映射器 XML 文件,那么也需要配置文件。这时有两种解决办法:第一种是手动在 MyBatis 的 XML 配置文件中的 <mappers> 部分中指定 XML 文件的类路径(没整合前的方法);第二种是设置工厂 bean 的 mapperLocations 属性。

(5)编写spring整合service层的文件:spring-service.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!--UserServiceImpl注入到IOC容器中-->
    <bean id="userServiceImpl" class="com.sxt.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

(6)编写applicationContext.xml文件,将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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="classpath:spring-dao.xml"/>
    <import resource="classpath:spring-service.xml"/>

</beans>

(7)编写测试代码,验证整合没有问题

package com.sxt.service;

import com.sxt.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class ServiceTest {
    
    
    @Test
    public void test(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = context.getBean("userServiceImpl", UserService.class);

        List<User> users = userService.findUsers();
        for (User user : users) {
    
    
            System.out.println(user);
        }

    }
}

至此,service层的代码就编写完成了,spring和mybat的整合也已经成功了。

4.controller层编写(基于springmvc框架)

(1)在pom.xml文件中引入servlet和jsp包、JSTL和分页插件(用于之后对查询到的数据进行分页展示)的依赖。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sxt</groupId>
    <artifactId>userSystem_SSM</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <!--mybatis环境-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!--mysql环境-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>
        <!--spring环境-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <!--mybatis和spring整合包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.2</version>
        </dependency>
        <!--servlet和jsp包-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <!-- JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- JSTL实现包 -->
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-impl</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!--单元测试junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!--日志输出log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.7.0</version>
        </dependency>
        <!--分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.1</version>
        </dependency>
    </dependencies>

    <!--开启资源过滤-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>

</project>

(2)编写springMVC的配置文件:spring-controller.xml。

注意:一定得配置静态资源过滤,不然之后写的页面的css、js等文件都无法加载。拦截器的作用就和之前Javaweb中的过滤器一样,都是用来实现项目中的登录验证功能的。

<?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">

    <!-- 开启SpringMVC注解驱动 -->
    <mvc:annotation-driven/>
    <!-- 静态资源过滤-->
    <mvc:default-servlet-handler/>
    <!--自动扫描web相关的bean-->
    <context:component-scan base-package="com.sxt.controller"/>

    <!--
    为了安全性考虑,我们的JSP文件都会放在WEB-INF下,
    但是我们在外部是不可以直接访问/WEB-INF/目录下的资源对吧,
    只能通过内部服务器进行转发的形式进行访问,InternalResourceViewResolver底层通过转发形式帮我们解决了这个问题!
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--关于拦截器的配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/** 包括路径及其子路径-->
            <mvc:mapping path="/**"/>
            <!--bean配置的就是拦截器-->
            <bean class="com.sxt.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

(3)修改总的spring配置文件:applicationContext.xml,导入spring-controller.xml,方便对三层的配置文件管理。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="classpath:spring-dao.xml"/>
    <import resource="classpath:spring-service.xml"/>
    <import resource="classpath:spring-controller.xml"/>

</beans>

(4)修改web.xml文件,主要就是配置DispatcherServlet。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--拦截器的静态资源过滤配置,虽然网上有说拦截器不拦截静态资源,但不配置的话静态资源确实无法加载-->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/img/*</url-pattern>
        <url-pattern>/js/*</url-pattern>
        <url-pattern>/css/*</url-pattern>
    </servlet-mapping>

    <!--注册DispatcherServlet-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <!--启动级别-1-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--/ 匹配所有的请求;(不包括.jsp)-->
    <!--/* 匹配所有的请求;(包括.jsp)-->
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--encodingFilter-->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>

    <!--Session过期时间30分钟-->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>

(5)新建一个包:con.sxt.controller,里面存放所有视图层的代码。在包下新建几个Java类:

  • Add.java(用于跳转到添加用户界面)
package com.sxt.controller;

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

@Controller
@RequestMapping("userSystem")
public class Add {
    
    

    @RequestMapping("/add")
    public String add(){
    
    
        return "add";
    }
}
  • AddUser.java(用于实现添加用户的功能)
package com.sxt.controller;

import com.sxt.pojo.User;
import com.sxt.service.UserService;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@Controller
@RequestMapping("userSystem")
public class AddUser {
    
    
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    @RequestMapping("addUser")
    public String addUser(HttpServletRequest request) throws UnsupportedEncodingException {
    
    
        //设置编码
        request.setCharacterEncoding("utf-8");
        //获取参数
        Map<String, String[]> map = request.getParameterMap();
        //封装对象
        User user = new User();
        try {
    
    
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        } catch (InvocationTargetException e) {
    
    
            e.printStackTrace();
        }
        userService.addUser(user);

        return "redirect:list";
    }
}
  • CheckCode.java(用于生成验证码)
package com.sxt.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@Controller
@RequestMapping("userSystem")
public class CheckCode {
    
    
    /**
     * 产生4位随机字符串作为验证码
     * @return
     */
    private String generateCheckCode(){
    
    
        String baseCode = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        int size = baseCode.length();
        Random r = new Random();
        StringBuffer sb = new StringBuffer();
        for(int i=1;i<=4;i++){
    
    
            //产生0到size-1的随机值
            int index = r.nextInt(size);
            //在baseCode字符串中获取下标为index的字符
            char c = baseCode.charAt(index);
            //将c放入到StringBuffer中去
            sb.append(c);
        }
        return sb.toString();
    }
    @RequestMapping("/code")
    public void getCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    

        //在内存中创建一个长80,宽30的图片,默认黑色背景; 参数一:长; 参数二:宽; 参数三:颜色
        int width = 80;
        int height = 30;
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        //获取画笔,设置画笔颜色为灰色,填充图片
        Graphics gp = image.getGraphics();
        gp.setColor(Color.gray);
        gp.fillRect(0,0,width,height);


        //产生4个随机验证码,将验证码放入HttpSession中
        String checkCode_server = generateCheckCode();
        //将验证码放入HttpSession中
        request.getSession().setAttribute("checkCode_server",checkCode_server);

        //设置画笔颜色为黄色,设置字体的小大为24,向图片上写入验证码
        gp.setColor(Color.YELLOW);
        gp.setFont(new Font("黑体",Font.BOLD,24));
        gp.drawString(checkCode_server,15,25);

        //将内存中的图片输出到浏览器 参数一:图片对象;参数二:图片的格式,如PNG,JPG,GIF;参数三:图片输出到哪里去
        ImageIO.write(image,"PNG",response.getOutputStream());
    }
}
  • DeleteSeletedUsers.java(用于批量删除选中用户)
package com.sxt.controller;

import com.sxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;

@Controller
@RequestMapping("userSystem")
public class DeleteSelectedUsers {
    
    
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    @RequestMapping("/deleteSelectedUsers")
    public String deleteUsers(int[] userBox){
    
    

        userService.deleteSelectedUsers(userBox);

        return "redirect:list";
    }
}
  • DeleteUser.java(用于删除某个用户)
package com.sxt.controller;

import com.sxt.pojo.User;
import com.sxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("userSystem")
public class DeleteUser {
    
    
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    @RequestMapping("/deleteUser")
    public String list(int id){
    
    
        userService.deleteUser(id);

        return "redirect:list";
    }
}
  • FindUserById.java(用于根据具体用户id查找某个用户)
package com.sxt.controller;

import com.sxt.pojo.User;
import com.sxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("userSystem")
public class FindUserById {
    
    
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    @RequestMapping("/findUserById")
    public String list(Model model,int id){
    
    
        User user = userService.findUserById(id);
        model.addAttribute("user",user);
        return "update";
    }
}
  • FindUsers.java(用于查询所有用户的信息)
package com.sxt.controller;

import com.github.pagehelper.PageHelper;
import com.sxt.pojo.User;
import com.sxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/userSystem")
public class FindUsers {
    
    

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    @RequestMapping("/list")
    public String list(Model model){
    
    
        PageHelper.startPage(1, 5);
        List<User> users = userService.findUsers();
        model.addAttribute("list",users);
        return "list";
    }

}
  • Login.java(用于实现登录功能)
package com.sxt.controller;

import com.sxt.pojo.Administrator;
import com.sxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;

@Controller
@RequestMapping("/userSystem")
public class Login {
    
    

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    @RequestMapping("/login")
    public String verify(String username,String password,Model model,HttpServletRequest request) throws UnsupportedEncodingException {
    
    
        //设置编码
        request.setCharacterEncoding("utf-8");
        //获取用户填写验证码
        String checkCode = request.getParameter("checkCode");
        //验证码校验
        HttpSession session = request.getSession();
        String checkCode_server = (String) session.getAttribute("checkCode_server");
        if(checkCode!=null){
    
    
            if(!checkCode_server.equalsIgnoreCase(checkCode)){
    
     //服务器端生成的验证码不等于用户填写的验证码
                //验证码不正确,提示信息
                model.addAttribute("msg","验证码错误");
                session.removeAttribute("checkCode_server");//确保验证码一次性
                return "login";
            }
        }
        Administrator administrator = userService.findAdministrator(username, password);
        if(administrator!=null){
    
    
            String username1 = administrator.getUsername();
            session.setAttribute("administrator",administrator);
            model.addAttribute("msg","登录成功,欢迎您"+username1);
            return "index";
        }else{
    
    
            model.addAttribute("msg","用户名或密码错误");
            return "login";
        }

    }

}
  • SignOut.java(用于实现退出功能)
package com.sxt.controller;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Controller
@RequestMapping("userSystem")
public class SignOut {
    
    

    @RequestMapping("/signOut")
    public void signOut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        HttpSession session = request.getSession();
        session.removeAttribute("administrator");
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }
}
  • UpdateUser(用于修改用户信息)
package com.sxt.controller;

import com.sxt.pojo.User;
import com.sxt.service.UserService;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@Controller
@RequestMapping("userSystem")
public class UpdateUser {
    
    
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    @RequestMapping("/updateUser")
    public String updateUser(HttpServletRequest request) throws UnsupportedEncodingException {
    
    
        //设置编码
        request.setCharacterEncoding("utf-8");
        //获取参数
        Map<String, String[]> map = request.getParameterMap();
        //封装对象
        User user = new User();
        try {
    
    
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        } catch (InvocationTargetException e) {
    
    
            e.printStackTrace();
        }
        userService.updateUser(user);

        return "redirect:list";
    }
}

(6)con.sxt.controller,里面存放拦截器的代码。在包下新建LoginInterceptor.java类,用于实现登录验证的功能:

package com.sxt.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginInterceptor implements HandlerInterceptor {
    
    

    //在请求处理的方法之前执行
    //如果返回true执行下一个拦截器
    //如果返回false就不执行下一个拦截器
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        HttpSession session = request.getSession();
        //获取资源请求路径
        String uri = request.getRequestURI();
        //判断是否包含登录相关资源路径
        if (uri.contains("/login")||uri.contains("/code")) {
    
    
            //包含,用户就是想登录。放行
            return true;
        } else {
    
    
            //不包含,需要验证用户是否登录
            //从获取session中获取user
            Object administrator = session.getAttribute("administrator");
            if (administrator != null) {
    
    
                //登录了放行
                return true;
            } else {
    
    
                //没有登录。跳转登录页面
                request.setAttribute("msg", "您尚未登录,请先登录");
                request.getRequestDispatcher("/login.jsp").forward(request,response);
                return false;
            }
        }
    }
}

(7)在webapp目录下新建文件夹:css(存放css库代码)、js(存放js库代码)、img(存放你网页的背景图片)。

在网上下载bootstrap的代码:bootstrap.cssbootstrap-theme.css,将其放入css文件夹中以及bootstrap.js将其放入js文件夹中。

在网上下载jQuery的代码:jquery-2.1.0.min.js,将其放入js文件夹中。

(8)编写页面。

在webapp目录下新建index.jsplogin.jsp文件,分别编写对应代码

  • index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>用户信息管理系统</title>
    <style>
        body{
            background-image: url("${pageContext.request.contextPath}/img/bk.jpg");
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
      div{
        margin-top: 20%;
      }

      a{
        text-decoration: none;
        font-size: 35px;
          color: purple;
      }
    </style>
</head>
<%--在WEB-INF下的所有页面或者资源,只能通过controller或者servlet进行访问--%>
<body>
<div align="center">
    <h1 style="text-align: center; color: #5bc0de">欢迎使用用户信息管理系统</h1>
    <hr color="orange"/>
    请先<a href="${pageContext.request.contextPath}/login.jsp" >
            登录
        </a>
</div>
</body>



</html>
  • login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>用户信息管理系统</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">

    <style>
        body{
            background-image: url("${pageContext.request.contextPath}/img/bk.jpg");
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
    </style>

    <script>
        function refreshCode(){
            //获取验证码图片对象
            var codeImg = document.getElementById("codeImg");
            //设置其src属性,加时间戳
            codeImg.src = "${pageContext.request.contextPath}/userSystem/code?time="+new Date().getTime();
        }
    </script>
</head>
<body>

<div class="container" style="width: 400px;margin-top: 200px">
    <h2 style="color: red;text-align: center;">管理员登录</h2>
    <form action="${pageContext.request.contextPath}/userSystem/login" method="post">
        <!-- 把标签和控件放在一个带有 class .form-group 的 <div> 中。这是获取最佳间距所必需的。-->
        <!-- 向所有的文本元素 <input>、<textarea> 和 <select> 添加 class ="form-control" -->
        <div class="form-group">
            <!-- for id	规定 label 绑定到哪个表单元素。-->
            <label for="username">用户名:</label>
            <input type="text" name="username" class="form-control" id="username" placeholder="请输入用户名" required/>
        </div>

        <div class="form-group">
            <label for="password">密码:</label>
            <input type="password" name="password" class="form-control" id="password" placeholder="请输入密码" required/>
        </div>

        <div class="form-inline">
            <label for="checkCode">验证码:</label>
            <input type="text" name="checkCode" class="form-control" id="checkCode" placeholder="请输入验证码" required/>
            <a href="javascript:refreshCode();" >
                <img alt="验证码" src="${pageContext.request.contextPath}/userSystem/code" id="codeImg" title="看不清换一张"/>
            </a>
        </div>
        <hr/>
        <div class="form-group" style="text-align: center">
            <input class="btn-primary" type="submit" value="登录">
        </div>

    </form>

    <!-- 出错显示的信息框 -->
    <div class="alert alert-warning alert-dismissible" role="alert">
        <button type="button" class="close" data-dismiss="alert" >
            <span>&times;</span>
        </button>
        <strong>${msg}</strong>
    </div>
</div>
</body>
</html>

在webapp的WEB-INF目录下新建一个jsp文件夹,在里面编写不想被直接访问到的页面代码。分别为add.jsp、index.jsp、list.jsp、login.jsp、update.jsp

  • add.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1:1 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>用户信息管理系统</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
    <!-- 2. jQuery导入,建议使用1.9以上的版本 -->
    <script src="${pageContext.request.contextPath}/js/jquery-2.1.0.min.js"></script>
    <!-- 3. 导入bootstrap的js文件 -->
    <script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>

    <style>
        body{
            background-image: url("${pageContext.request.contextPath}/img/bk.jpg");
            background-size: 100% 100%;
            background-repeat: no-repeat;
        }
        .container{
            width: 40%;
        }
    </style>
</head>

<body>
<div class="container">
    <h3 style="text-align: center;color: orangered">添加联系人页面</h3>
    <form action="${pageContext.request.contextPath}/userSystem/addUser" method="post">
        <div class="form-group">
            <label for="name">姓名:</label>
            <input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名" required/>
        </div>

        <div class="form-group">
            <label>性别:</label>
            <label>
                <input type="radio" name="gender" value="男" checked="checked"/>
            </label>男
            <label>
                <input type="radio" name="gender" value="女"/>
            </label>女
        </div>

        <div class="form-group">
            <label for="age">年龄:</label>
            <input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄" required/>
        </div>

        <div class="form-group">
            <label for="address">籍贯:</label>
            <select name="address" class="form-control" id="address">
                <option value="上海">上海</option>
                <option value="北京">北京</option>
                <option value="深圳">深圳</option>
                <option value="广州">广州</option>
            </select>
        </div>

        <div class="form-group">
            <label for="qq">QQ:</label>
            <input type="text" class="form-control" id="qq" name="qq" placeholder="请输入QQ号码" required/>
        </div>

        <div class="form-group">
            <label for="email">Email:</label>
            <input type="text" class="form-control" id="email" name="email" placeholder="请输入邮箱地址" required/>
        </div>

        <div class="form-group" style="text-align: center">
            <input class="btn btn-primary" type="submit" value="提交" />
            <input class="btn btn-danger" type="reset" value="重置" />
            <input class="btn btn-default" type="button" value="返回"
           οnclick="window.location.href='${pageContext.request.contextPath}/userSystem/list'"/>
        </div>
    </form>
</div>
</body>


</html>
  • index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>用户信息管理系统</title>
    <style>
        body{
            background-image: url("${pageContext.request.contextPath}/img/bk.jpg");
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
      div{
        margin-top: 20%;
      }

      a{
        text-decoration: none;
        font-size: 35px;
          color: purple;
      }
    </style>
</head>


<body>
<a href="${pageContext.request.contextPath}/userSystem/signOut" style="color: black">退出
</a>
<div align="center">
    <span>${msg}</span>
    <h1 style="text-align: center; color: #5bc0de">欢迎您使用用户信息管理系统</h1>
    <hr color="orange"/>
    <a href="${pageContext.request.contextPath}/userSystem/list" >
            查询所有用户信息
    </a>
</div>
</body>



</html>
  • list.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1:1 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>用户信息管理系统</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
    <!-- 2. jQuery导入,建议使用1.9以上的版本 -->
    <script src="${pageContext.request.contextPath}/js/jquery-2.1.0.min.js"></script>
    <!-- 3. 导入bootstrap的js文件 -->
    <script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>

    <style type="text/css">
        td, th {
            text-align: center;
        }

        body{
            background-image: url("${pageContext.request.contextPath}/img/bk.jpg");
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
    </style>

    <script>
        function deleteUser(id){
            //用户安全提示
            if(confirm("您确定要删除吗?")){
                //访问路径
                location.href="${pageContext.request.contextPath}/userSystem/deleteUser?id="+id;
            }
        }
        window.onload = function (){
            //给删除选中按钮添加单击事件
            document.getElementById("delSelected").onclick = function(){
                var flag = false;
                //判断是否有选中条目
                var cbs = document.getElementsByName("userBox");
                for (var i = 0; i < cbs.length; i++) {
                    if(cbs[i].checked){
                        //有一个条目选中了
                        flag = true;
                        break;
                    }
                }
                if(flag){//有条目被选中
                    if(confirm("您确定要删除选中条目吗?")){
                        //表单提交
                        document.getElementById("form").submit();
                    }
                }
            }
            //获取第一个总选框(全选全不选功能的实现)
            document.getElementById("generalBox").onclick = function(){
                //获取下边列表中所有的选择框
                var boxes = document.getElementsByName("userBox");
                //遍历
                for (var i = 0; i < boxes.length; i++) {
                    //4.设置这些cbs[i]的checked状态 = firstCb.checked
                    boxes[i].checked = this.checked;
                }
            }
        }
    </script>
</head>
<body>
<div class="container">
    <h3 style="text-align: center;font-size: 30px;color: orange">用户信息列表</h3>
    <div style="float: left;">
        <form class="form-inline" action="${pageContext.request.contextPath}" method="post">
            <div class="form-group">
                <label for="queryName">姓名</label>
                <input type="text" name="name" class="form-control" id="queryName">
            </div>
            <div class="form-group">
                <label for="queryAddress">籍贯</label>
                <input type="text" name="address" class="form-control" id="queryAddress">
            </div>
            <div class="form-group">
                <label for="queryEmail">邮箱</label>
                <input type="text" name="email" class="form-control" id="queryEmail">
            </div>
            <button type="submit" class="btn btn-default">查询</button>
        </form>
    </div>

    <div style="float: right;">
        <a class="btn btn-primary" href="${pageContext.request.contextPath}/userSystem/add">添加联系人</a>
        <a class="btn btn-primary" href="javascript:void(0);" id="delSelected">删除选中</a>
    </div>

    <form id="form" action="${pageContext.request.contextPath}/userSystem/deleteSelectedUsers" method="post">
        <table border="1" class="table table-bordered table-hover">
            <tr class="success">
                <th><input type="checkbox" id="generalBox"></th>
                <th>编号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>籍贯</th>
                <th>QQ</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>

            <%--items:容器对象,varStatus:循环状态对象,属性count表示循环的次数--%>
            <c:forEach items="${list}" var="user" varStatus="s">
                <tr>
                    <td><input type="checkbox" name="userBox" value="${user.id}"></td>
                        <%--<td>${s.count+(pb.rows)*(pb.currentPage-1)}</td>--%>
                    <td>${user.id}</td>
                    <td>${user.name}</td>
                    <td>${user.gender}</td>
                    <td>${user.age}</td>
                    <td>${user.address}</td>
                    <td>${user.qq}</td>
                    <td>${user.email}</td>
                    <td><a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/userSystem/findUserById?id=${user.id}">修改</a>&nbsp;
                        <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id})" id="delete">删除</a></td>
                </tr>

            </c:forEach>
        </table>
    </form>

    
</div>

</body>
</html>

  • login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>用户信息管理系统</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">

    <style>
        body{
            background-image: url("${pageContext.request.contextPath}/img/bk.jpg");
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
    </style>

    <script>
        function refreshCode(){
            //获取验证码图片对象
            var codeImg = document.getElementById("codeImg");
            //设置其src属性,加时间戳
            codeImg.src = "${pageContext.request.contextPath}/userSystem/code?time="+new Date().getTime();
        }
    </script>
</head>
<body>
<div class="container" style="width: 400px;margin-top: 200px">
    <h2 style="color: red;text-align: center;">管理员登录</h2>
    <form action="${pageContext.request.contextPath}/userSystem/login" method="post">
        <!-- 把标签和控件放在一个带有 class .form-group 的 <div> 中。这是获取最佳间距所必需的。-->
        <!-- 向所有的文本元素 <input>、<textarea> 和 <select> 添加 class ="form-control" -->
        <div class="form-group">
            <!-- for id	规定 label 绑定到哪个表单元素。-->
            <label for="username">用户名:</label>
            <input type="text" name="username" class="form-control" id="username" placeholder="请输入用户名" required/>
        </div>

        <div class="form-group">
            <label for="password">密码:</label>
            <input type="password" name="password" class="form-control" id="password" placeholder="请输入密码" required/>
        </div>

        <div class="form-inline">
            <label for="checkCode">验证码:</label>
            <input type="text" name="checkCode" class="form-control" id="checkCode" placeholder="请输入验证码" required/>
            <a href="javascript:refreshCode();" >
                <img alt="验证码" src="${pageContext.request.contextPath}/userSystem/code" id="codeImg" title="看不清换一张"/>
            </a>
        </div>
        <hr/>
        <div class="form-group" style="text-align: center">
            <input class="btn-primary" type="submit" value="登录">
        </div>

    </form>

    <!-- 出错显示的信息框 -->
    <div class="alert alert-warning alert-dismissible" role="alert">
        <button type="button" class="close" data-dismiss="alert" >
            <span>&times;</span>
        </button>
        <strong>${msg}</strong>
    </div>
</div>
</body>
</html>
  • update.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html lang="zh-CN">
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>用户信息管理系统</title>

    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
    <script src="${pageContext.request.contextPath}/js/jquery-2.1.0.min.js"></script>
    <script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
    <style>
        body{
            background-image: url("${pageContext.request.contextPath}/img/bk.jpg");
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
        .container{
            width: 40%;
        }
    </style>
</head>

<body>
    <div class="container">
    <h3 style="text-align: center;color: red">修改用户信息</h3>
        <form action="${pageContext.request.contextPath}/userSystem/updateUser" method="post">
            <!--  隐藏域 提交id-->
            <input type="hidden" name="id" value="${user.id}">

          <div class="form-group">
            <label for="name">姓名:</label>
            <input type="text" class="form-control" id="name" name="name"  value="${user.name}" readonly="readonly" placeholder="不可更改姓名" />
          </div>

          <div class="form-group">
            <label>性别:</label>
              <c:if test="${user.gender == '男'}">
                  <label>
                      <input type="radio" name="gender" value="男" checked />
                  </label>男
                  <label>
                      <input type="radio" name="gender" value="女"  />
                  </label>女
              </c:if>

              <c:if test="${user.gender == '女'}">
                  <label>
                      <input type="radio" name="gender" value="男"  />
                  </label>男
                  <label>
                      <input type="radio" name="gender" value="女" checked  />
                  </label>女
              </c:if>
          </div>

          <div class="form-group">
            <label for="age">年龄:</label>
            <input type="text" class="form-control" value="${user.age}" id="age"  name="age" placeholder="请输入年龄" />
          </div>

          <div class="form-group">
            <label for="address">籍贯:</label>
             <select name="address" id="address" class="form-control" >
                 <c:if test="${user.address == '上海'}">
                    <option value="上海" selected>上海</option>
                    <option value="北京">北京</option>
                    <option value="深圳">深圳</option>
                    <option value="广州">广州</option>
                 </c:if>

                 <c:if test="${user.address == '北京'}">
                     <option value="上海">上海</option>
                     <option value="北京" selected>北京</option>
                     <option value="深圳">深圳</option>
                     <option value="广州">广州</option>
                 </c:if>

                 <c:if test="${user.address == '深圳'}">
                     <option value="上海">上海</option>
                     <option value="北京">北京</option>
                     <option value="深圳" selected>深圳</option>
                     <option value="广州">广州</option>
                 </c:if>

                 <c:if test="${user.address == '广州'}">
                     <option value="上海">上海</option>
                     <option value="北京">北京</option>
                     <option value="深圳">深圳</option>
                     <option value="广州"  selected>广州</option>
                 </c:if>
            </select>
          </div>

          <div class="form-group">
            <label for="qq">QQ:</label>
            <input type="text" id="qq" class="form-control" value="${user.qq}" name="qq" placeholder="请输入QQ号码"/>
          </div>

          <div class="form-group">
            <label for="email">Email:</label>
            <input type="text" id="email" class="form-control" value="${user.email}" name="email" placeholder="请输入邮箱地址"/>
          </div>

          <div class="form-group" style="text-align: center">
            <input class="btn btn-primary" type="submit" value="提交" />
            <input class="btn btn-danger" type="reset" value="重置" />
            <input class="btn btn-default" type="button" value="返回"
            οnclick="window.location.href='${pageContext.request.contextPath}/userSystem/list'"/>
          </div>
        </form>
    </div>
</body>
</html>

至此,SSM整合全部结束,具体的业务逻辑代码和前端展示代码也都编写完成,剩下的就是在浏览器中测试了。

5.启动服务器,部署项目,进行测试

这里和之前的所有web项目的步骤都一样,在此不再赘述,具体对应着自己的习惯进行测试即可。

猜你喜欢

转载自blog.csdn.net/weixin_51426754/article/details/120123106