前言
开发工具:IDEA
1 创建项目
File > New > Module...

1.1 开发环境IDEA配置
设置maven配置
File > Settings > Build, Execution, Deployment > Build Tools > Maven

设置jdk版本
File > Project Structure

设置Tomcat

添加项目到Tomcat

1.2 pom.xml导入依赖
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>idea_maven</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.10</version>
</dependency>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.42</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
1.3 创建ServletAnnoInitConfig.java
(相当于web.xml)
java
package com.example.config;
import javax.servlet.Filter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletAnnoInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
1.4 创建SpringMvcConfig.java
(相当于springmvc-servlet.xml)
java
package com.example.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringMvcConfig {
}
1.5 创建SpringConfig.java
(相当于applicationContext.xml)
java
package com.example.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
}
2 过滤器
ServletAnnoInitConfig.java
java
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[] {filter};
}
3 拦截器
SpringMvcConfig.java
实现 WebMvcConfigurer接口
添加扫描注解 @ComponentScan(com.example.interceptor)
添加扫描注解 @EnableWebMvc// SpringMvcConfig内容生效
java
package com.example.config;
import com.example.interceptor.ApiInterceptor;
import com.example.interceptor.LoginInterceptor;
import com.example.interceptor.PermissionInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@ComponentScan({"com.example.interceptor"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ApiInterceptor apiInterceptor;
@Autowired
private LoginInterceptor loginInterceptor;
@Autowired
private PermissionInterceptor permissionInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/‌**")
.excludePathPatterns("/","/login"); //不拦截路径;
registry.addInterceptor(permissionInterceptor)
.addPathPatterns("/admin/**", "/user/**") // 拦截路径
.excludePathPatterns("/user/login", "/user/register"); //不拦截路径
registry.addInterceptor(apiInterceptor).addPathPatterns("/‌**"); // 参数用以来注入
}
}
创建拦截器类
实现接口(HandlerInterceptor)或者继承类(HandlerInterceptorAdapter无需实现全部方法)
PermissionInterceptor
java
package com.example.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@Component
public class PermissionInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
response.getWriter().write("PermissionInterceptor Run");
return true;
}
}
LoginInterceptor
java
package com.example.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle执行了");
request.setAttribute("startTime", System.currentTimeMillis());
Object user = request.getSession().getAttribute("user");
if (user == null) {
response.sendRedirect(request.getContextPath() + "/");
return false; // 终止
}
return true; // 继续
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle执行了");
if (modelAndView != null) {
modelAndView.addObject("globalMsg", "请求成功");
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion执行了");
long startTime = (Long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis();
System.out.println("运行时间" + (endTime - startTime) + "ms");
}
}
ApiInterceptor
java
package com.example.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class ApiInterceptor implements HandlerInterceptor {
@Value("0:0:0:0:0:0:0:1")
private String allowedIp;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
String clientIp = request.getRemoteAddr();
if (!allowedIp.equals(clientIp)) {
response.setStatus(403);
response.getWriter().write("Forbidden: IP not allowed");
return false;
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
}
4 控制器
SpringMvcConfig.java (添加congroller扫描)
java
package com.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan({"com.example.interceptor", "com.example.controller"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
}
创建控制器类
LoginController
java
package com.example.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.pojo.User;
import com.example.service.LoginService;
@Controller
public class LoginController{
@Autowired
private LoginService service;
@RequestMapping("/login")
public String login(HttpServletRequest req, HttpServletResponse res) throws Exception {
String username = req.getParameter("user");
if (username == null || username.isEmpty()) {
req.setAttribute("msg", "登录失败");
return "Login";
}
User user = service.getUser(username);
if (user == null) {
req.setAttribute("msg", "不存在用户");
return "Login";
} else {
req.getSession().setAttribute("user", username);
req.setAttribute("msg", "登录成功");
return "Home";
}
}
}
LogoutController
java
package com.example.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LogoutController {
@RequestMapping("/logout")
public String logout(HttpServletRequest req, HttpServletResponse res) {
req.getSession().invalidate();
req.setAttribute("msg", "登出成功");
return "Login";
}
}
创建对应页面
src/main/webapp/WEB-INF/jsp/Login.jsp
html
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
if(request.getAttribute("msg") != null){
%>
${msg}
<%
}
%>
<br/>
登录页面Spring3.2<br/>
<form name="form1" action="/login" method="post">
<input type="text" name="user" />
<input type="password" name="password" />
<button>登录</button>
</form>
</body>
</html>
src/main/webapp/WEB-INF/jsp/Home.jsp
html
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
${msg}
<br/>
<form action="/logout" method="post">
<button>logout</button>
</form>
</body>
</html>
5 数据库访问
连接数据库: mysql -hlocalhost -P3306 -uroot -proot
创建数据库: create database maven1;
切换数据库: use maven1;
创建数据库表: create table user(username varchar(20) primary key, password varchar(20) not null);
5.1 创建Mybatis配置类
MybatisConfig.java
java
package com.example.config;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
public class MybatisConfig {
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer m = new MapperScannerConfigurer ();
m.setBasePackage("com.example.mapper"); //扫描mapper包
return m;
}
}
5.2 业务逻辑代码
创建Model类
java
package com.example.pojo;
import lombok.Data;
@Data
public class User {
private String username;
private String password;
}
创建LoginMapper.java
java
package com.example.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.example.pojo.User;
@Mapper
public interface LoginMapper {
public User selectUserById(@Param("username") String username);
public List<User> selectAllUsers();
public int insertUser(User user);
public int updateUser(User user);
public int deleteUser(@Param("username") String username);
}
创建LoginMapper.xml
XML
src/main/resources/com/example/mapper/UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.LoginMapper">
<!-- 查询用户ById -->
<select id="selectUserById" resultType="com.example.pojo.User">
SELECT username, password
FROM user
WHERE username = #{username}
</select>
<!-- 查询所有用户 -->
<select id="selectAllUsers" resultType="list">
SELECT username, password
FROM user
ORDER BY username ASC
</select>
<!-- 插入新用户 -->
<insert id="insertUser" parameterType="com.example.pojo.User" >
INSERT INTO user (username, password)
VALUES (#{username}, #{password})
</insert>
<!-- 更新用户信息 -->
<update id="updateUser" parameterType="com.example.pojo.User">
UPDATE user
SET username = #{username},
password = #{password}
WHERE username = #{username}
</update>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="long">
DELETE FROM user WHERE username = #{username}
</delete>
</mapper>
创建LoginService
java
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.mapper.LoginMapper;
import com.example.pojo.User;
@Service
@Transactional
public class LoginService {
@Autowired
private LoginMapper dao;
public User getUser(String username) {
return dao.selectUserById(username);
}
}
5.3 SpringConfig.java添加配置
创建数据库连接信息(resources/jdbc.properties)
java
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/maven1
jdbc.username=root
jdbc.password=root
创建JdbcConfig.java
java
package com.example.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import com.alibaba.druid.pool.DruidDataSource;
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
// 配置数据源
@Bean
public DruidDataSource druidDataSource() {
DruidDataSource d = new DruidDataSource();
d.setDriverClassName(driver);
d.setUrl(url);
d.setUsername(username);
d.setPassword(password);
return d;
}
// 配置事务控制
@Bean
public PlatformTransactionManager transactionManager(DruidDataSource datasource) {
DataSourceTransactionManager ds = new DataSourceTransactionManager();
ds.setDataSource(datasource);
return ds;
}
}
SpringConfig.java添加扫描
java
package com.example.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@PropertySource("classpath:jdbc.properties") // 加载properties文件
@Import({JdbcConfig.class}) // 导入数据源实现类
@EnableTransactionManagement // 启动事务管理注解
public class SpringConfig {
}
5.4 整合mybatis
MybatisConfig.java
java
package com.example.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import com.alibaba.druid.pool.DruidDataSource;
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DruidDataSource ds){
SqlSessionFactoryBean b = new SqlSessionFactoryBean();
b.setTypeAliasesPackage("com.example.pojo"); //用于自动类型转换
b.setDataSource(ds);
return b;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer m = new MapperScannerConfigurer ();
m.setBasePackage("com.example.mapper"); //扫描mapper包
return m;
}
}
5.5 扫描Bean
SpringConfig.java
java
package com.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@ComponentScan({"com.example.service"})
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class, MybatisConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
6 视图
6.1 视图解析器
SpringMvcConfig.java
java
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/jsp/", ".jsp");
}
6.2 视图控制器
SpringMvcConfig.java
java
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("Login");
}
7 扩展功能
静态资源访问
SpringMvcConfig.java
java
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**") // 满足条件请求不走拦截器
.addResourceLocations("/WEB-INF/css/"); //走指定的资源访问
}
新建css样式
/WEB-INF/css/sytle.css
java
body {
color: blue;
}
Login.jsp添加样式
html
<link rel="stylesheet" href="../css/style.css">
启动服务器

(1) 首页访问

(2) 登录

(3) 错误用户名登录

(4) 正确用户名登录

(5) 登出

IDEA启动Tomcat控制台乱码解决
Help > Edit Custom VM Options(文件末尾添加 -Dfile.encoding=UTF-8,重启 IDEA)

Run > Edit Configurations,在 Tomcat Server 的 VM options 中添加-Dfile.encoding=UTF-8
