WEB框架搭建-maven-spring-springjdbc-springMVC-redis

项目环境要求:
windows7
jdk1.8
apache-tomcat-8.0.53
eclipse
apache-maven-3.3.9
mysql

框架技术要求:
spring
springjdbc
springMVC
redis

下载和安装链接
maven安装包和maven安装步骤
https://download.csdn.net/download/qq_29914837/10672813
apache-tomcat-8.0.53下载和安装步骤
https://download.csdn.net/download/qq_29914837/10672823
jdk1.8下载和安装步骤
https://download.csdn.net/download/qq_29914837/10672804
redis-64.3.0.503下载和安装

1.前期准备

新建一个工作区间,配置工作区间环境(window-preferences)
全部改为UTF-8,如图
在这里插入图片描述

在这里插入图片描述

配置安装maven,我这里是settings-person.xml,这是我自己重命名了的,安装包中的一般都是settings.xml
在这里插入图片描述

配置server(tomcat)
在这里插入图片描述

配置validation验证,解决每次保存项目时会长时间验证等待的问题,注意Manual不变,Build值勾选Classpath Dependency Validator项
在这里插入图片描述

配置新建的jsp页面默认为UTF-8编码,避免重复修改
在这里插入图片描述

在这里插入图片描述

前期准备工作完成,就可以开始创建maven项目了。

2.创建一个maven项目

在这里插入图片描述

勾选第二项,点击next
在这里插入图片描述
在这里插入图片描述

点击finish完成创建
在这里插入图片描述

项目建立完成后需要调整项目的目录结构
Src/main/java 为正式环境的java代码
Src/main/resources 为正式环境的资源文件
Src/test/java 为测试环境的java代码
Src/rest/resources 为测试环境的资源文件
注意:此处新建选择source folder
source folder 设计出来就是用来放待编译的java文件
folder 就是最普通的文件
在这里插入图片描述

最后建立的目录结构
在这里插入图片描述

配置maven项目的参数和环境(右击项目–>properties)

Depoyment Assembly :配置源目录文件相对应的部署路径,我这里配置正式环境的部署路径为WEB-INF/classes,配置测试环境的部署路径为WEB-INF/test-classes
在这里插入图片描述

配置java Bulid Path (重要)
java build path面板的功能梳理
Source标签页,指定本工程的源码目录和输出目录。
Projects标签页,指定本工程所依赖的其他工程。
Libraries标签页,指定本工程所需的jar包和class目录等。
add external jars = 增加工程外部的包
add jars = 增加工程内包
add library = 增加一个库
add class folder = 增加一个类文件夹
Order And Export标签页,指定本工程的编译引用顺序和导出内容等。
在这里插入图片描述

在这里插入图片描述

选择java编译版本
在这里插入图片描述

设置“Dynamic Web Module”为3.0,java版本为1.8(注意:先设置java为1.8,保存后,再设置 Dynamic Web Module”为3.0)
在这里插入图片描述

如果项目出现:Cannot change version of project facet Dynamic web module to 3.0的提示信息,则参考下面解决方案,否则跳过此步骤。
原因:该开始选择会报错会提示选择不了这是因为新建项目的时候用了maven-artchetype-webapp由于这个catalog比较老,用的servlet还是2.3的
解决方案:
打开web.xml文件,修改头部为

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

然后 点击window --> show view --> Navigator 打开org.eclipse.wst.common.project.facet.core.xml文件,或者在项目的工作区间中搜索org.eclipse.wst.common.project.facet.core.xml文件

在这里插入图片描述

返回查看,Dynamic Web Module已变为3.0
在这里插入图片描述
Eclipse Maven 编译错误 Dynamic Web Module 3.0 requires Java 1.6 or newer 解决方案
在这里插入图片描述
但是 Eclipse 明明已经将编译级别设置为 1.8:
这是由于你的 Maven 编译级别是 jdk1.5 或以下,而你导入了 jdk1.6 以上的依赖包:查看 Eclipse 的 Navigator 视图下该项目的 .classpath 文件:

<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">  
    <attributes>  
        <attribute name="maven.pomderived" value="true"/>  
    </attributes>  
</classpathentry>  

解决办法:
使用 maven-compiler-plugin 将 maven 编译级别改为 jdk1.6 以上:

		<build>
		<finalName>spring-weixin</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source><!-- 源代码开发版本 -->
					<target>1.8</target><!-- java编译版本 -->
					<encoding>UTF8</encoding> <!-- 项目的编码 -->
				</configuration>
			</plugin>
		</plugins>
	</build>

右击项目-maven - update 即可

最后新建server-将web项目部署到服务器上,启动tomcat

在这里插入图片描述

(备注:如果项目的jsp页面出错,是因为没有servlet的相关jar包,需要在
Pom.xml中配置)

		<!-- 加入Servlet Jar 包 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<!-- 配置为私有作用域,保证执行时不会将该jar包放置到到项目的依赖库中 -->
			<scope>provided</scope>
		</dependency>

打开浏览器:http://127.0.0.1:8080/maven-springmvc-spring-springjdbc/
如果没有成功打开页面,则查看配置参数和环境

3.在maven项目上搭建框架

首先建议如图的项目结构目录
在这里插入图片描述

User.java 用户实体类

package com.entity.test.user;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name="user")
public class User implements Serializable {
	
	private Integer id;//主键id
	private String username;//用户名
	private String password;//密码

	public User() {
	}

	public User(Integer id, String username, String password) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
	}

	@Column(name="username",length = 10, nullable = true)
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Column(name="password",length = 10, nullable = true)
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Column(name="id",length = 10, nullable = true)
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

}

UserController.java 用户控制层类

package com.controller.test.user;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.entity.test.user.User;
import com.service.test.user.UserService;
import com.util.exception.ExceptionUtil;

/**
 * 所属类别:控制层方法类(用户)测试
 * 用途:用户功能方法
 * version:1.0
 */
@Controller
@RequestMapping(value="/user")
public class UserController {


    @Autowired
    private UserService userService;

    public UserController() {
    }

    //用户登录方法
    @RequestMapping(value="/login", method=RequestMethod.POST)
    public String login(String username, String password, HttpSession session){
        if (null == username || "".equals(username.trim())) {
            throw new ExceptionUtil("用户名不能为空");
        }

        User user = userService.getUserByUsername(username);
        if (null == user) {
            throw new ExceptionUtil("用户名不存在");
        }

        if (!user.getPassword().equals(password)) {
            throw new ExceptionUtil("密码不正确");
        }

        session.setAttribute("loginUser", user);
        return "redirect:/user/users";
    }
    
    //用户列表
    @RequestMapping(value="users", method=RequestMethod.GET)
    public String list(Model model){
        Map<String, User> users = new HashMap<String, User>();
        for (User user : userService.getAllUsers()) {
            users.put(user.getUsername(), user);
        }

        model.addAttribute("users", users);
        return "test/list";
    }

    //进入添加界面
    @RequestMapping(value="add", method=RequestMethod.GET)
    public String add(@ModelAttribute("user") User user){
        return "test/add";
    }

    //添加
    @RequestMapping(value="add", method=RequestMethod.POST)
    public String add(@Validated User user, BindingResult br, @RequestParam(value="attach") MultipartFile[] attachs, HttpServletRequest req) throws IOException{
        if (br.hasErrors()) {
            return "test/add";
        }

        String realPath = req.getSession().getServletContext().getRealPath("/resources/upload");

        for (int i = 0; i < attachs.length; i++) {
            MultipartFile attach = attachs[i];
            if (attach.isEmpty()) {
                continue;
            }

            File attachFile = new File(realPath + "/" + attach.getOriginalFilename());
            FileUtils.copyInputStreamToFile(attach.getInputStream(), attachFile);
            System.out.println(realPath + "/" + attach.getOriginalFilename());

            System.out.println(attach.getName());
            System.out.println(attach.getOriginalFilename());
            System.out.println(attach.getContentType());
        }

        userService.register(user);
        return "redirect:/user/users";
    }

    //展示用户
    @RequestMapping(value="/{username}/show", method=RequestMethod.GET)
    public String show(@PathVariable String username, Model model){
        model.addAttribute(userService.getUserByUsername(username));
        return "test/show";
    }

    //展示用户
    @RequestMapping(value="/{username}/show", method=RequestMethod.GET, params="json")
    @ResponseBody
    public User show(@PathVariable String username){
        return userService.getUserByUsername(username);
    }

    //进入编辑页面
    @RequestMapping(value="/{username}/update", method=RequestMethod.GET)
    public String update(@PathVariable String username, Model model){
        model.addAttribute(userService.getUserByUsername(username));
        return "test/update";
    }

    //编辑
    @RequestMapping(value="/{username}/update", method=RequestMethod.POST)
    public String update(@PathVariable String username, @Validated User user, BindingResult br){
        if(br.hasErrors()){
            return "test/update";
        }

        userService.update(user);
        return "redirect:/user/users";
    }

    //删除
    @RequestMapping(value="/{username}/delete", method=RequestMethod.GET)
    public String delete(@PathVariable String username){
        userService.removeUser(username);
        return "redirect:/user/users";
    }

    //注销
    @RequestMapping(value="/logout", method=RequestMethod.GET)
    public String logout(HttpSession session){
        session.removeAttribute("loginUser");
        return "index";
    }

/*    //异常处理
    @ExceptionHandler(value={ExceptionUtil.class})
    public String handleLocalException(ExceptionUtil e, HttpServletRequest req){
        req.setAttribute("error", e);
        return "test/error";
    }
*/

}

web.xml 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

	<display-name>Archetype Created Web Application</display-name>
	<welcome-file-list>
		<welcome-file>/WEB-INF/views/index.jsp</welcome-file>
	</welcome-file-list>

	<!-- Spring监听 -->
	<listener>
		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
	</listener>

	<!-- ApplicationContext 的Listener配置方式 start -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
    classpath*:spring/applicationContext*.xml
    
    </param-value>
	</context-param>
	<!-- ApplicationContext 的Listener配置方式 end -->

	<!-- springmvc -->
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 自定义spring mvc的配置文件名称和路径 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springMVC/spring-servlet.xml</param-value>
		</init-param>
		<!-- 自定义启动顺序,让这个Servlet随Servlet容器一起启动 -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>spring</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<!-- 编码过虑 -->
	<filter>
		<filter-name>setcharacter</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>setcharacter</filter-name>
		<url-pattern>/</url-pattern>
	</filter-mapping>

	<!-- 解决HTTP PUT请求Spring无法获取请求参数的问题 -->
	<filter>
		<filter-name>HiddenHttpMethodFilter</filter-name>
		<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>HiddenHttpMethodFilter</filter-name>
		<servlet-name>springMVC3</servlet-name>
	</filter-mapping>

	<!-- 异常处理 -->
	<!-- 接收空指针错误 -->
	<error-page>
		<exception-type>java.lang.NullPointerException</exception-type>
		<location>/WEB-INF/views/commons/error/error_web_null.jsp</location>
	</error-page>
	<!-- 404 页面不存在错误 -->
	<error-page>
		<error-code>404</error-code>
		<location>/WEB-INF/views/commons/error/error_web_404.jsp</location>
	</error-page>
	<!-- 接收405错误 -->
	<error-page>
		<error-code>405</error-code>
		<location>/WEB-INF/views/commons/error/error405.jsp</location>
	</error-page>
	<!--  500 服务器内部错误 -->
	<error-page>
		<error-code>500</error-code>
		<location>/WEB-INF/views/commons/error/error500.jsp</location>
	</error-page>

</web-app>

UserDao.java 用户的Dao层接口

package com.dao.test.user;

import java.util.List;

import com.entity.test.user.User;

public interface UserDao {

	//用户注册
	public void register(User user);

	//根据用户名查找用户
	public User findUserByUserName(final String userName);

	//查询用户集合
	public List<User> findAllUser();

    //删除用户(通过用户名)
	public boolean deleteByUsername(String username);

	//编辑更新用户
	public boolean update(User user);
}

UserDaoImpl.java 用户Dao层实现类

package com.dao.test.user;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.dao.test.user.UserDao;
import com.entity.test.user.User;

@Repository("userDao")
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public UserDaoImpl(){
    }

    public void register(User user) {
        String sqlStr = "insert into user(userName,password) values(?,?)";
        Object[] params = new Object[]{user.getUsername(),user.getPassword()};
        jdbcTemplate.update(sqlStr, params);
    }

    public User findUserByUserName(String userName) {
        String sqlStr = "select * from user where userName = ?" ;
        List<User> users = jdbcTemplate.query(sqlStr,new Object[]{userName} , new UserRowMapper());
        if (null != users && !users.isEmpty()) {
            return users.get(0);
        }
        return null;
    }

    @Override
    public boolean deleteByUsername(String username){
        int updateNum = jdbcTemplate.update("delete from user where username = '" + username + "'");

        if (updateNum != 1) {
            return false;
        }

        return true;
    }

    @Override
    public List<User> findAllUser() {
        return jdbcTemplate.query("select * from user", new UserRowMapper());
    }

    private static class UserRowMapper implements RowMapper <User> {

        public User mapRow(ResultSet rs, int rowNum) throws SQLException {
            int i = 1;
            User user = new User();
            user.setId(rs.getInt(i++));
            user.setUsername(rs.getString(i++));
            user.setPassword(rs.getString(i++));
            return user;
        }

    }

    @Override
    public boolean update(User user) {
        return jdbcTemplate.update("update user set password = " + user.getPassword() + " where username = '" + user.getUsername() + "'") == 1 ? true : false;
    }

}

UserService.java 用户service层接口

package com.service.test.user;

import java.util.List;

import com.entity.test.user.User;

public interface UserService {
	
	public boolean register(User user);

	public User loginCheck(User user);

	public List<User> getAllUsers();

	public boolean removeUser(String username);

	public User getUserByUsername(String username);

	public boolean update(User user);
}

UserServiceImpl.java 用户service层实现类

package com.service.test.user;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dao.test.user.UserDao;
import com.entity.test.user.User;

@Service("userService")
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDao userDao;
	public UserServiceImpl() {
	}

	@Override
	public List<User> getAllUsers() {
		return userDao.findAllUser();
	}

	@Override
	public boolean register(User user) {
		User u = userDao.findUserByUserName(user.getUsername());

		if (u == null || u.getId() == null || u.getId() == 0) {
			userDao.register(user);
			return true;
		} else {
			System.out.println("id=" + u.getId() + ",  userName=" + u.getUsername() + ", password=" + u.getPassword());
			return false;
		}
	}

	@Override
	public User loginCheck(User user) {
		User u = userDao.findUserByUserName(user.getUsername());
		System.out.println("id=" + u.getId() + ",  userName=" + u.getUsername() + ", password=" + u.getPassword());
		if (user.getPassword().equals(u.getPassword())) {
			return u;
		} else {
			return null;
		}
	}

	@Override
	public boolean removeUser(String username) {
		if (userDao.deleteByUsername(username)) {
			return true;
		}

		return false;
	}

	@Override
	public User getUserByUsername(String username) {
		return userDao.findUserByUserName(username);
	}

	@Override
	public boolean update(User user) {
		return userDao.update(user);
	}

}

resource资源文件的目录结构如图所示
在这里插入图片描述

jdbc.properties (连接数据库的配置资源文件信息)

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/framework
jdbc.username=root
jdbc.password=123456

log4j.properties (日志输出资源文件)

log4j.rootLogger=DEBUG,A1
# \u8f93\u51fa\u5230\u63a7\u5236\u53f0 
log4j.appender.A1=org.apache.log4j.ConsoleAppender 
log4j.appender.A1.layout=org.apache.log4j.PatternLayout 
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} [\u65E5\u5FD7\u4FE1\u606F] %m%n

applicationContext_spring.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" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
       http://www.springframework.org/schema/util 
       http://www.springframework.org/schema/util/spring-util-4.1.xsd">

    <!-- 加载JDBC、log、redis配置文件 -->
    <context:property-placeholder location="classpath:properties/*.properties" />

    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass">
            <value>${jdbc.driverClassName}</value>
        </property>
        <property name="jdbcUrl">
            <value>${jdbc.url}</value>
        </property>
        <property name="user">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
        <!--连接池中保留的最小连接数。 -->
        <property name="minPoolSize">
            <value>5</value>
        </property>
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize">
            <value>30</value>
        </property>
        <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
        <property name="initialPoolSize">
            <value>10</value>
        </property>
        <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime">
            <value>60</value>
        </property>
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement">
            <value>5</value>
        </property>
        <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 
                                    如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
        <property name="maxStatements">
            <value>0</value>
        </property>
        <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
        <property name="idleConnectionTestPeriod">
            <value>60</value>
        </property>
        <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
        <property name="acquireRetryAttempts">
            <value>30</value>
        </property>
        <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 
                                    获取连接失败后该数据源将申明已断开并永久关闭。Default: false -->
        <property name="breakAfterAcquireFailure">
            <value>true</value>
        </property>
        <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 
                                    等方法来提升连接测试的性能。Default: false -->
        <property name="testConnectionOnCheckout">
            <value>false</value>
        </property>
    </bean>

    <!-- 配置Jdbc模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 提供对lob字段的支持 -->
    <bean id="nativeJdbcExtractor"
        class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"
        lazy-init="true" />

    <!--如果底层数据库是 DB2、SQL Server、MySQL 等非 Oracle 的其它数据库,则只要简单配置一个 DefaultLobHandler-->
    <bean id="lobHandler"
        class="org.springframework.jdbc.support.lob.DefaultLobHandler"
        lazy-init="true" />

    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        p:dataSource-ref="dataSource" />

    <!-- 通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 -->
   <!--  <aop:config proxy-target-class="true"> 
        <aop:pointcut id="serviceMethod"
            expression=" execution(* com.service..*(..))" />
        <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice> -->

</beans>

applicationContext.xml (把多个配置文件集成在一个配置文件中,方便操作)其中redis的配置文件可以先跳过,后续会讲解

<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
       http://www.springframework.org/schema/util 
       http://www.springframework.org/schema/util/spring-util-4.1.xsd">

       <!-- 导入spring配置文件 -->
       <import resource="classpath:spring/applicationContext_spring.xml" />
       <!-- 导入redis配置文件 -->
       <import resource="classpath:spring/applicationContext_redis.xml" />

</beans>

ExceptionUtil.java 自定义异常类

package com.util.exception;

/**
 * 所属类别:工具类
 * 用途:自定义的异常类
 * @author yilei
 * version:1.0
 */
public class ExceptionUtil extends RuntimeException {

	public ExceptionUtil(String string) {
		super(string);
	}

}

TestException.java 异常测试类

package com.controller.test.exception;


import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.util.exception.ExceptionUtil;

@Controller
@RequestMapping(value = "/exception")
public class TestException   {

	@RequestMapping("/exception/{id}")
	@ResponseBody
	public Object hello(@PathVariable String id) {
        if(id.equals("0")){
        	 throw new ExceptionUtil("自定义有异常");
        }else if (id.equals("1")) {// NullPointerException控制值异常
			throw new NullPointerException("空指针异常");
		} else if (id.equals("2")) {// 数学运算异常
			int value = 1 / 0;
			return "java.lang.ArithmeticException";
		} else {
			return "ok";
		}
	}	
	
    //异常处理,基于注解的方式,但是需要进行自定义异常的类中都写一个相同的方法才可生效。如果使用这种方式。
/*    @ExceptionHandler(value={ExceptionUtil.class})
    public String handleLocalException(ExceptionUtil e, HttpServletRequest req){
        req.setAttribute("error", e);
        return "error/error";
    }*/

}

spring-servlet.xml (springmvc的配置资源文件)

<?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:jee="http://www.springframework.org/schema/jee"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/jee
       http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
       http://www.springframework.org/schema/util 
       http://www.springframework.org/schema/util/spring-util-4.1.xsd">

    <!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
    <context:annotation-config />
    <context:component-scan base-package="com.controller" />
    <context:component-scan base-package="com.service" />
    <context:component-scan base-package="com.dao" />

     <!-- 注解驱动 -->
    <mvc:annotation-driven />
    <!-- 资源映射 ,可以访问resource下的静态文件-->
    <mvc:resources mapping="/resources/**" location="/resources/" />

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

    <!-- Invokes Spring MVC @Controller methods -->  
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="webBindingInitializer">  
            <!-- Configures Spring MVC DataBinder instances -->  
            <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">  
                <property name="validator" ref="validator" />  
            </bean>  
        </property>  

        <!-- <property name="messageConverters">  
            <util:list id="beanList">  
                <ref bean="mappingJacksonHttpMessageConverter"/>  
            </util:list>  
        </property>   -->
    </bean> 

    <!-- 输出对象转JSON支持 -->  
    <bean id="jsonConverter"  
        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>  
    <bean  
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="messageConverters">  
            <list>  
                <ref bean="jsonConverter" />  
            </list>  
        </property>  
    </bean>  

    <!-- <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
        <property name="supportedMediaTypes">  
            <list>  
                <value>text/html;charset=UTF-8</value>  
            </list>  
        </property>  
    </bean>   -->

    <!-- Creates the JSR-303 Validator -->  
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

    <!-- 配置一个MultipartResolver,在这里我们使用支持Commons FileUpload的CommonsMultipartResolver:  -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8" p:maxUploadSize="5000000"/>



     <!-- Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver-全局异常配置 start -->     
      <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
       <!--  默认的错误信息页面-->
        <property name="defaultErrorView" value=">commons/error/error"/>
        <property name="exceptionMappings">
            <props>
                <!-- 自定义的异常类 -->
                <prop key="com.util.exception.ExceptionUtil">commons/error/error_spring_ExceptionUtil</prop> 
                <!-- 空指针异常 -->
                <prop key="java.lang.NullPointerException">commons/error/error_spring_null</prop>
                <!-- 数学算术异常 -->
                <prop key="java.lang.ArithmeticException">commons/error/error_spring_math</prop>
            </props>
        </property>
    </bean>    
     <!-- 全局异常配置 end -->   


</beans>

备注:如果对springMVC中的异常处理过程不太清楚的话,可以参考本人的另一篇博文,有详细结合了本项目讲解了异常处理过程和几种方式特点
springMVC的几种异常处理方式
https://blog.csdn.net/qq_29914837/article/details/82697089

接下来是jsp页面的建立,如图所示,其中error文件下的jsp文件,为异常处理页面,可以帮助大家更好的理解集中异常处理方式的区别和特点,实际项目运用中,保留一到两个页面即可。

在这里插入图片描述

error_spring_ExceptionUtil.jsp (用于springmvc中配置的自定义异常时输出)

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
error_spring_ExceptionUtil.jsp<br>
spirngmvc配置异常-自定义异常
</body>
</html>

error.jsp (用于springmvc中配置的自定义异常(基于注解方式)时输出)

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>
    异常抛出处理
</title>
</head>
<body>
    <h1>${error.message}</h1>
</body>
</html>

error_spring_math.jsp (用于springmvc中配置的数学算术运行异常时输出)

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
error_spring_math.jsp<br>
spirngmvc配置异常-数学算术运算异常
</body>
</html>

error_spring_null.jsp (用于springmvc中配置的空指针异常时输出)

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>
页面发生错误
</title>
</head>
<body>
    <h1> error_spring_null.jsp <br> springmvc异常处理-空指针异常</h1>
</body>
</html>

error_web_404.jsp (用于web.xml中配置的404异常时输出)

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
error_web_404.jsp
  web.xml配置的404异常
</body>
</html>

error_web_null.jsp (用于web.xml中配置的空指针异常时输出)

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>
页面发生错误
</title>
</head>
<body>
error_web_null.jsp
    <h1>web.xml配置的空指针异常</h1>
</body>
</html>

add.jsp ( 添加用户)

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>
   添加用户
</title>
</head>
<body>
<sf:form method="post"  action="add" modelAttribute="user" enctype="multipart/form-data">
    编号:<sf:input path="id" /><sf:errors path="id"></sf:errors><br>
    姓名:<sf:input path="username"/><sf:errors path="username"></sf:errors><br>
    密码:<sf:input path="password"/><sf:errors path="password"></sf:errors><br>
    文件:<input type="file" name="attach"><br>
    文件:<input type="file" name="attach"><br>
    <input type="submit" value="添加用户">
</sf:form>

</body>
</html>

list.jsp(用户列表)

<%@page import="com.entity.test.user.User"%>
<%@page import="org.eclipse.jdt.internal.compiler.batch.Main"%>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	User user = (User) session.getAttribute("loginUser");
	boolean isLogin = null == user ? false : true;
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>用户列表展示</title>
<link rel="stylesheet" href="<%=request.getContextPath()%>/resources/main.css" type="text/css">

</head>
<body>
	<div style="text-align: center; ">
		<a href="add">添加用户</a>
		<h1>
			欢迎${loginUser.username}的到来!
			<c:if test="<%=isLogin%>">
				<a href="logout">注销</a>
			</c:if>
		</h1>
		<br>
	<table align="center" border="1">
		<td>用户编号</<td>
		<td>用户姓名</<td>
		<td>用户密码</<td>
		<td>操作</<td>
		<c:forEach items="${users}" var="uentry">
         <tr>
           <td>${uentry.value.id}</td>
           <td><a href="${uentry.value.username}/show">${uentry.value.username}</a></td>
           <td>${uentry.value.password}</td>
           <td><a href="${uentry.value.username}/update">编辑</a> <a href="${uentry.value.username}/delete">删除</a></td>
          </tr>

		</c:forEach>
	</table>
	</div>
</body>
</html>

show.jsp(查看用户)

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>
    用户展示页面
</title>
</head>
<body>
    编号: ${user.id}<br>
    姓名: ${user.username}<br>
    密码: ${user.password}<br>
    <a href="user/users">返回用户列表展示界面</a>
</body>
</html>

update.jsp(编辑用户)

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>
    用户编辑界面
</title>
</head>
<body>
<sf:form method="post" action="update" modelAttribute="user">
    编号:<sf:input path="id" /><sf:errors path="id"></sf:errors><br>
    姓名:<sf:input path="username"/><sf:errors path="username"></sf:errors><br>
    密码:<sf:input path="password"/><sf:errors path="password"></sf:errors><br>
    <input type="submit" value="修改用户">
</sf:form>

</body>
</html>

index.jsp (首页,用户登录界面)

<%@ page language="java" contentType="text/html; utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>用户登录界面</title>
</head>

<body>
<div style="text-align: center;margin: 200px;">
	登录界面
	<br>

	<form action="user/login" method="post">
		姓         名:<input name="username" type="text"><br>
		密        码:<input name="password" type="text"><br> 
		<input type="submit" value="登录">
	</form>

</div>
</body>
</html>

pom.xml maven依赖配置

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.yi</groupId>
	<artifactId>maven-springmvc-spring-springjdbc</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>maven-springmvc-spring-springjdbc Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<spring.version>4.3.10.RELEASE</spring.version>
	</properties>

	<dependencies>
		<!-- 加入Servlet Jar 包 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<!-- 配置为私有作用域,保证执行时不会将该jar包放置到到项目的依赖库中 -->
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.5</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.35</version>
		</dependency>

		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5</version>
		</dependency>

		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.1.2.Final</version>
		</dependency>

		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>


		<!-- json -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.5.2</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-core-asl</artifactId>
			<version>1.9.13</version>
		</dependency>

		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.13</version>
		</dependency>
		<!-- json -->

		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>1.4.7</version>
		</dependency>

		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
			<scope>provided</scope>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.eclipse.persistence/javax.persistence -->
		<dependency>
			<groupId>org.eclipse.persistence</groupId>
			<artifactId>javax.persistence</artifactId>
			<version>2.1.1</version>
		</dependency>

		<!-- Redis客户端 -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.9.0</version>
		</dependency>
		<!-- redis Spring 基于注解配置 -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			<version>1.7.2.RELEASE</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>maven-springmvc-spring-springjdbc</finalName>
	</build>
</project>

静态css、js文件如图所示
在这里插入图片描述

引用方法

<link rel="stylesheet" href="<%=request.getContextPath()%>/resources/main.css" type="text/css">

运行sql,建立用户表(已插入一条数据,admin,123456)



SET FOREIGN_KEY_CHECKS=0;

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(50) NOT NULL AUTO_INCREMENT,
  `userName` varchar(30) DEFAULT NULL,
  `password` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;


INSERT INTO `user` VALUES ('1', 'admin', '123456');

按照要求建立以上全部文件即可

4.启动项目

启动项目,打开浏览器
http://127.0.0.1:8080/maven-springmvc-spring-springjdbc

在这里插入图片描述

在这里插入图片描述

5.在spring中集成redis

项目搭建基本完成,如果需要集成redis请参考本人另一篇博文
https://blog.csdn.net/qq_29914837/article/details/82686359

发布了168 篇原创文章 · 获赞 213 · 访问量 20万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览