前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SSM整合-基于IDEA社区版和Maven-案例入门

SSM整合-基于IDEA社区版和Maven-案例入门

作者头像
用户2225445
发布2022-11-12 17:07:43
6450
发布2022-11-12 17:07:43
举报
文章被收录于专栏:IT从业者张某某IT从业者张某某

SSM整合-基于IDEA社区版和Maven-案例入门

SSM整合-基于IDEA社区版和Maven

中实现了SSM整合,现在进行一个基本的案例。

1 系统功能概述

2 数据库设计

2.1在ssm数据库下创建user表:

代码语言:javascript
复制
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名',
  `realname` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '真实姓名',
  `password` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '密码',
  `gender` tinyint(1) UNSIGNED NULL DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

2.2 在ssm数据库下创建employee表

代码语言:javascript
复制
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '学生姓名',
  `score` double(10, 2) NULL DEFAULT NULL COMMENT '学生成绩',
  `photo` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像路径',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

3 用户登录模块

3.1 创建User实体类:

代码语言:javascript
复制
package edu.hncj.ssm.pojo;

public class User {
    private Integer id;
    private String username;
    private String realname;
    private String password;
    private Boolean gender;

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    public String getPassword() {
        return password;
    }

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

    public Boolean getGender() {
        return gender;
    }

    public void setGender(Boolean gender) {
        this.gender = gender;
    }

    public User() {
    }

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

3.2 创建UserMapper接口:

在edu.hncj.ssm.mapper包下创建UserMapper接口

代码语言:javascript
复制
package edu.hncj.ssm.mapper;
import edu.hncj.ssm.pojo.User;

public interface UserMapper {

    //根据用户查询用户
    User findByUserName(String username);

    //保存用户信息
    void save(User user);

}

在resources的edu/hncj/ssm/mapper目录下创建UserMapper.xml

代码语言:javascript
复制
<?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="edu.hncj.ssm.mapper.UserMapper">
    <!--findByUserName-->
    <select id="findByUserName" parameterType="String" resultType="User">
        select id,username,realname,password,gender from `user`
        where username = #{username}
    </select>

    <!--save-->
    <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        insert into `user` values(#{id},#{username},#{realname},#{password},#{gender})
    </insert>

</mapper>

3.3 创建service接口和实现类:

UserSerivice:

代码语言:javascript
复制
package edu.hncj.ssm.service;

import edu.hncj.ssm.pojo.User;

public interface UserService {

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

    //用户登录
    User login(String username, String password);
}

UserSeriviceImpl:

代码语言:javascript
复制
package edu.hncj.ssm.service.impl;


import edu.hncj.ssm.mapper.UserMapper;
import edu.hncj.ssm.pojo.User;
import edu.hncj.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import java.nio.charset.StandardCharsets;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userDao;

    @Autowired
    public UserServiceImpl(UserMapper userDao) {
        this.userDao = userDao;
    }


    @Override//xiaochen  123 ====>     xiaochen   xxed
    public User login(String username, String password) {
        //1.根据用户名查询用户
        User user = userDao.findByUserName(username);
        if(ObjectUtils.isEmpty(user)) throw new RuntimeException("用户名不正确!");
        //2.比较密码
        String passwordSecret = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        if(!user.getPassword().equals(passwordSecret)) throw new RuntimeException("密码输入错误!");
        return user;
    }

    @Override
    public void register(User user) {
        //1.根据用户名查询数据库中是否存在改用户
        User userDB = userDao.findByUserName(user.getUsername());
        //2.判断用户是否存在
        if(!ObjectUtils.isEmpty(userDB)) throw new RuntimeException("当前用户名已被注册!");
        //3.注册用户&明文的密码加密  特点: 相同字符串多次使用md5就行加密 加密结果始终是一致
        String newPassword = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
        user.setPassword(newPassword);
        userDao.save(user);
    }
}

3.4 创建二维码生成类

VerifyCodeUtils类

代码语言:javascript
复制
package edu.hncj.ssm.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;

/**
 */
public class VerifyCodeUtils {

    /**
     * 输出指定验证码图片流
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, w, h);

        g2.setColor(Color.gray);// 设置背景色
        g2.fillRect(0, 2, w, h-4);

        g2.setColor(Color.blue);
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);
        }

        g2.dispose();
        ImageIO.write(image, "jpg", os);
    }
}

3.5 创建UserController类:

代码语言:javascript
复制
package edu.hncj.ssm.controller;


import edu.hncj.ssm.pojo.User;
import edu.hncj.ssm.service.UserService;
import edu.hncj.ssm.utils.VerifyCodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Controller
@RequestMapping("user")
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    private UserService userService;

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


    /**
     * 安全退出
     */
    @RequestMapping("logout")
    public String logout(HttpSession session) {
        session.invalidate(); //session失效
        return "redirect:/user/login";//跳转到登录界面
    }

    /**
     * 用户登录
     *
     * @return
     */
    @RequestMapping("login")
    public String login(String username, String password, HttpSession session) {
        log.debug("本次登录用户名: {}", username);
        log.debug("本地登录密码: {}", password);
        try {
            //1.调用业务层进行登录
            User user = userService.login(username, password);
            //2.保存用户信息
            session.setAttribute("user", user);
        } catch (Exception e) {
            e.printStackTrace();
            return "login";//登录失败回到登录界面
        }
        return "redirect:/student/lists";//登录成功之后,跳转到查询所有员工信息控制器路径
    }

    /**
     * 用户注册
     *
     * @return
     */
    @RequestMapping("register")
    public String register(User user, String code, HttpSession session) {
        log.debug("用户名: {},真是姓名: {},密码: {},性别: {},", user.getUsername(), user.getRealname(), user.getPassword(), user.getGender());
        log.debug("用户输入验证码: {}", code);

        try {
            //1.判断用户输入验证码和session中验证码是否一致
            String sessionCode = session.getAttribute("code").toString();
            if (!sessionCode.equalsIgnoreCase(code)) throw new RuntimeException("验证码输入错误!");
            //2.注册用户
            userService.register(user);
        } catch (RuntimeException e) {
            e.printStackTrace();
            return "register"; //注册失败回到注册
        }
        return "redirect:/user/login";  //注册成功跳转到登录
    }

    /**
     * 生成验证码
     */
    @RequestMapping("generateImageCode")
    public void generateImageCode(HttpSession session, HttpServletResponse response) throws IOException {
        //1.生成4位随机数
        //  String code = VerifyCodeUtils.generateVerifyCode(4);
        String code = "1235";
        //2.保存到session作用域
        session.setAttribute("code", code);
        //3.根据随机数生成图片 && 4.通过response响应图片  && 5.设置响应类型
        response.setContentType("image/png");
        ServletOutputStream os = response.getOutputStream();
        VerifyCodeUtils.outputImage(220, 60, os, code);
    }

}

3.6 创建login.html视图

代码语言:javascript
复制
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>用户登录</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" type="text/css" th:href="@{/css/style.css}"/>
</head>

<body>
<div id="wrap">
    <div id="top_content">
        <div id="header">
            <div id="topheader">
                <h1 id="title">
                    <a href="#">main</a>
                </h1>
            </div>
            <div id="navigation">
            </div>
        </div>
        <div id="content">
            <p id="whereami">
            </p>
            <h1> 欢迎进入,请登录! </h1>
            <form th:action="@{/user/login}" method="post">
                <table cellpadding="0" cellspacing="0" border="0"
                       class="form_table">
                    <tr>
                        <td valign="middle" align="right">用户名:</td>
                        <td valign="middle" align="left">
                            <input type="text" class="inputgri" name="username"/>
                        </td>
                    </tr>
                    <tr>
                        <td valign="middle" align="right">密码:</td>
                        <td valign="middle" align="left">
                            <input type="password" class="inputgri" name="password"/>
                        </td>
                    </tr>
                </table>
                <p>
                    <input type="submit" class="button" value="点我登录 &raquo;"/>

                    <a href="register">还没有账号,立即注册</a>
                </p>
            </form>
        </div>
    </div>
    <div id="footer">
        <div id="footer_bg">
            123@qq.com
        </div>
    </div>
</div>
</body>
</html>

3.7 创建register.html视图

代码语言:javascript
复制
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
	<head>
		<title>用户注册</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}" />
	</head>
	<body>
		<div id="wrap">
			<div id="top_content">
					<div id="header">
						<div id="topheader">
							<h1 id="title">
								<a href="#">main</a>
							</h1>
						</div>
						<div id="navigation">
						</div>
					</div>
				<div id="content">
					<p id="whereami"></p>
					<h1>注册</h1>
					<form th:action="@{/user/register}" method="post">
						<table cellpadding="0" cellspacing="0" border="0"
							class="form_table">
							<tr>
								<td valign="middle" align="right">用户名:</td>
								<td valign="middle" align="left">
									<input type="text" class="inputgri" name="username" />
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">真实姓名:</td>
								<td valign="middle" align="left">
									<input type="text" class="inputgri" name="realname" />
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">密码:</td>
								<td valign="middle" align="left">
									<input type="password" class="inputgri" name="password" />
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">性别:</td>
								<td valign="middle" align="left">
									男<input type="radio" class="inputgri" name="gender" value="1" checked="checked"/>
									女<input type="radio" class="inputgri" name="gender" value="0"/>
								</td>
							</tr>
							
							<tr>
								<td valign="middle" align="right">
									验证码:
									<img id="num" th:src="@{/user/generateImageCode}" />
									<a href="javascript:;" onclick="changeImageCode()">换一张</a>
									<script>
										function changeImageCode(){
											document.getElementById('num').src = '[[@{/user/generateImageCode}]]?'+(new Date()).getTime()
										}
									</script>
								</td>
								<td valign="middle" align="left">
									<input type="text" class="inputgri" name="code" />
								</td>
							</tr>
						</table>
						<p>
							<input type="submit" class="button" value="立即注册 &raquo;" />
							<a href="login">已有账号,返回登录</a>
						</p>
					</form>
				</div>
			</div>
			<div id="footer">
				<div id="footer_bg">
					123@qq.com
				</div>
			</div>
		</div>
	</body>
</html>

3.8 创建style.css

在src/main/webapp/css/style.css

代码语言:javascript
复制
body {
    margin: 0;
    font-size: 62.5%;
    font-family: Verdana, Arial, Helvetica, sans-serif;
    padding: 15px 0;
    background: #eeeeee;
}

#wrap {
    width: 820px;
    margin: 0 auto;
}

#top_content {
    padding: 0 10px;
}

#topheader {
        padding: 25px 15px 15px 15px;
        margin: 0 auto 0 auto;
        color: #85C329;
}

#rightheader {
    float: right;
    width: 375px;
    height: 40px;
    text-align: right;
}
#rightheader p {
    padding: 35px 15px 0 0;
    margin: 0;
    text-align: right;

}
#rightheader p span {
    font-weight: bold;
}
#rightheader a:link, #rightheader a:visited {
    text-decoration: underline;
}

#title {
    padding: 0;
    margin: 0;
    font-size: 2.5em;
}
#title span {
    font-size: 0.5em;
    font-style: italic;
}
#title a:link, #title a:visited {
    text-decoration: none;
}
#title a:hover {
    color: #E1F3C7;
}

#navigation {
    background: #85c329;
    height: 25px;
    clear: both
}
#navigation ul {
    padding: 0;
    margin: 0;
    list-style: none;
    font-size: 1.1em;
    height: 25px;
}
#navigation ul li {
    display: inline;
}
#navigation ul li a {
    color: #FFFFFF;
    display: block;
    text-decoration: none;
    float: left;
    line-height: 25px;
    padding: 0 16px;
    border-right: 1px solid #ffffff;
}
#navigation ul li a:hover {
    background: #5494F3;
}

#content {
    padding: 0 15px;
    margin: 0 auto 0 auto;
    color: #666666;
}

#content p#whereami {
    padding: 20px 0 15px 0;
    margin: 0;
}
#whereami a:link, #whereami a:visited {
    color: #73A822;
    text-decoration: underline;
}


#content h1, #content h2,
#content h3, #content h4 , #content h5 {
    color: #74A8F5;
}
#content h1 {
    font-family: "Trebuchet MS", Arial, Helvetica;
    padding: 0;
    margin: 0 0 15px 0;
    font-size: 2em;
}
#content h2 {
    font-family: "Trebuchet MS", Arial, Helvetica;
    padding: 0;
    margin: 0 0 15px 0;
    font-size: 1.5em;
}

#top_body, #content_body {
    padding: 0 25px;
}

#footer {
    color: #FFFFFF;
    padding: 0 10px 13px 10px;
}
#footer p {
    padding: 0;
    margin: 0;
}
#footer p a:link, #footer p a:visited {
    color: #FFFFFF;
    font-style: italic;
    text-decoration: none;
}
#footer #footer_bg {
    color: #85C329 ;
    padding: 15px 15px 25px 15px;
    border-top: 1px solid #7BB425;
}

#footer #design {
    display: block;
    width: 150px;
    height: 30px;
    float: right;
    line-height: 20px;
    padding: 0 5px;
    text-align: right;
    color: #E1F3C7;
}
#footer #design a {
    color: #FFFFFF;
    text-decoration: underline;
}

.table {
    margin-bottom: 15px;
    width: 100%;
    border-collapse: collapse;
}
.table_header td {
    padding: 5px 10px;
    color: rgb(70,122,167);
    border-top: 1px solid #CBD6DE;
    border-bottom: 1px solid #ADBECB;
    font-size: 1.1em;
    font-weight: bold;
}
.table_header td a:link, .table_header td a:visited {
    text-decoration: underline;
    color: rgb(70,122,167);
}
.table_header td a:hover {
    text-decoration: underline;
    color: #73A822;
}
.table_header td {
    border: 1px solid #CBD6DE;
}

.row1 td, .row2 td, .row_hover td, .paging_row td {
    padding: 5px 10px;
    color: #666666;
    border: 1px solid #CBD6DE;
}
.row1 td {
    background: #ffffff;
}
.row2 td {
    background: #eeeeee;
}
.row_hover td {
    background: #FBFACE;
    color: #000000;
}

.hidden {
    display: none;
}

.little {
    font-size: 10px;
}

.clear {
    clear: both;
}

.img_left {
    float: left;
    padding: 1px;
    border: 1px solid #cccccc;
    margin: 0 10px 10px 0;
    width: 110px;
    height:150px;
}

/* #content ul basic style for unordered lists
------------------------------------------------*/
#content ul {
    font-size: 1.1em;
    line-height: 1.8em;
    margin: 0 0 15px 0;
    padding: 0;
    list-style-type: none;
}

/* #content p paragraphs
-----------------------------*/
#content p {
    font-size: 1.2em;
    margin: 0;
    padding: 0 0 15px 0;
}

/* #content p a links in paragraphs
------------------------------------*/
#content p a:link, #content p a:visited,
.table a:link, .table a:visited,
.link a {
    color: #73A822;
    text-decoration: none;
}
#content p a:hover, .table a:hover, .link a:hover {
    text-decoration: underline;
}

/* #content ul.green (73A822)
--------------------------------*/
#content ul.green li {
    padding: 0 0 0 20px;
    margin: 0;
    font-size: 1.1em;
}
#content ul.green li a:link, #content ul.green li a:visited {
    color: #73A822;
    text-decoration: none;
}
#content ul.green li a:hover {
    color: #73A822;
    text-decoration: underline;
}

/* #content ul.black (73A822)
--------------------------------*/
#content ul.black li {
    padding: 0 0 0 20px;
    margin: 0;
    font-size: 1.1em;
}
#content ul.black li a:link, #content ul.black li a:visited {
    color: #666666;
    text-decoration: none;
}
#content ul.black li a:hover {
    color: #999999;
    text-decoration: underline;
}

/* #content ol
--------------------------------*/
#content ol {
    padding: 0 0 0 25px;
    margin: 0 0 15px 0;
    line-height: 1.8em;
}

#content ol li {
    font-size: 1.1em;
}
#content ol li a:link, #content ol li a:visited {
    color: #73A822;
    text-decoration: none;
}
#content ol li a:hover {
    color: #73A822;
    text-decoration: underline;
}

/* #content p.paging 
---------------------------------*/
#content p.paging {
padding: 5px;
border: 1px solid #CBD6DE;
text-align: center;
margin-bottom: 15px;
background: #eeeeee;
}

/* .small_input smaller text in inputs/combos
-----------------------------------------------*/
.small_input {
    font-size: 10px;
}

/* .form_table style for table used in forms
---------------------------------------------*/
.form_table {
    margin-bottom: 15px;
    font-size: 1.1em;
}
.form_table p {
    margin: 0;
    padding: 0;
}
.form_table td {
    padding: 5px 10px;
}

/* .checkbox_nomargins clear all margins from a checkbox
---------------------------------------------------------*/
.checkbox_nomargins {
    margin: 0;
    padding: 0;
}

/* .button some buttons style - inspired from wordpress
------------------------------*/
input.button {
    margin: 0;
    padding: 2px;
    border: 3px double #999999;
    border-left-color: #ccc;
    border-top-color: #ccc;
    font-size: 11px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}

/* form style for forms
-------------------------*/
form {
    padding: 0;
    margin: 0;
}

/* input.inputgri - some style for inputs
--------------------------------------------*/
input.inputgri, select.inputgri, textarea.inputgri {
    background: #eeeeee;
    font-size: 14px;
    border: 1px solid #cccccc;
    padding: 3px;
}
input.inputgri:focus, select.inputgri:focus , textarea.inputgri:focus {
    background: #ffffff;
    border: 1px solid #686868;
}

/* .notice - messages to user
--------------------------------*/
.notice {
    background: #CAEA99;
    border: 1px solid #70A522;
    padding: 15px 15px 15px 15px;
    margin-bottom: 15px;
    font-size: 1.2em;
    color: #333333;
}
.notice_error {
    background: #FEDCDA;
    border: 1px solid  #CE090E;
    padding: 15px 15px 15px 15px;
    margin-bottom: 15px;
    font-size: 1.2em;
    color: #333333;
}
#notice a {
    color: #333333;
    text-decoration: underline;
}

/* Other links 
----------------*/
.other_links {
    background: #eeeeee;
    border-top: 1px solid #cccccc;
    padding: 5px;
    margin: 0 0 15px 0;
}
#content .other_links h2 {
    color: #999999;
    padding: 0 0 0 3px;
    margin: 0;
}
#content .other_links ul {
    padding: 0;
    margin: 0;
}
#content .other_links ul li {
    padding: 0 0 0 20px;
}
#content .other_links a, #content .other_links a:visited {
    color: #999999;
    text-decoration: underline;
}
#content .other_links a:hover {
    color: #666666;
}

/* code */
code {
    font-size: 1.2em;
    color: #73A822;
}

3.9 创建拦截器LoginHandlerInterceptor

在edu.hncj.ssm.config下创建LoginHandlerInterceptor:

代码语言:javascript
复制
package edu.hncj.ssm.config;

import org.springframework.web.servlet.HandlerInterceptor;

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

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 登录成功应该有session(在登陆的Controller中设置session)
        Object admin = request.getSession().getAttribute("user");
        System.out.println(admin);
        if (admin == null){
            request.setAttribute("msg", "没有权限,请先登录!");
            request.getRequestDispatcher("/user/login").forward(request, response);
            return false;
        }else {
            return true;
        }
    }
}

配置拦截器:

在springmvc中添加拦截器配置

代码语言:javascript
复制
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 所有请求都拦截-->
            <mvc:mapping path="/**"/>
            <!--   放行登录界面和登陆请求-->
            <mvc:exclude-mapping path="/user/login"/>
            <mvc:exclude-mapping path="/user/register"/>
            <mvc:exclude-mapping path="/user/generateImageCode"/>
            <mvc:exclude-mapping path="/css/**"/>
            <mvc:exclude-mapping path="/upload/**"/>
            <mvc:exclude-mapping path="/js/**"/>
            <!--   拦截器类的位置-->
            <bean class="edu.hncj.ssm.config.LoginHandlerInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

4 用户管理模块

4.1 创建Student实体类

在 edu.hncj.ssm.pojo 下创建 Student类

代码语言:javascript
复制
package edu.hncj.ssm.pojo;

public class Student {
    private Integer id;
    private String name;
    private Double score;
    private String photo;//头像路径

    public Student() {
    }

    public Student(Integer id, String name, Double score, String photo) {
        this.id = id;
        this.name = name;
        this.score = score;
        this.photo = photo;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }
}

4.2 创建StudentMapper接口

在edu.hncj.ssm.mapper包下创建StudentMapper接口:

代码语言:javascript
复制
package edu.hncj.ssm.mapper;

import edu.hncj.ssm.pojo.Student;
import java.util.List;

public interface StudentMapper {

    //学生列表
    List<Student> lists();

    //保存学生信息
    void save(Student student);

    //根据id查询一个
    Student findById(Integer id);

    //更新学生信息
    void update(Student student);

    //删除学生信息
    void delete(Integer id);
}

在resources的edu/hncj/ssm/mapper目录下创建StudentMapper.xml

代码语言:javascript
复制
<?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="edu.hncj.ssm.mapper.StudentMapper">
    <!--lists-->
    <select id="lists" resultType="Student">
        select id,name,score,photo from `student`
    </select>


    <!--save-->
    <insert id="save" parameterType="Student" useGeneratedKeys="true" keyProperty="id">
        insert into `student` values (#{id},#{name},#{score},#{photo})
    </insert>


    <!--findById-->
    <select id="findById" parameterType="Integer" resultType="Student">
        select id,name,score,photo from `student`
        where id = #{id}
    </select>

    <!--update-->
    <update id="update" parameterType="Student" >
        update `student` set name=#{name},score=#{score},photo=#{photo}
        where id = #{id}
    </update>

    <!--delete-->
    <delete id="delete" parameterType="Integer">
        delete from `student` where id = #{id}
    </delete>

</mapper>

4.3 创建StudentService接口和实现类StudentServiceImpl

在edu.hncj.ssm.service下创建StudentService。

代码语言:javascript
复制
package edu.hncj.ssm.service;

import edu.hncj.ssm.pojo.Student;

import java.util.List;

public interface StudentService {

    //学生列表方法
    List<Student> lists();

    //保存学生信息
    void save(Student student);

    //根据id查询一个
    Student findById(Integer id);

    //更新学生信息
    void update(Student student);

    //删除学生信息
    void delete(Integer id);
}

在edu.hncj.ssm.service.impl下创建StudentServiceImpl

代码语言:javascript
复制
package edu.hncj.ssm.service.impl;


import edu.hncj.ssm.mapper.StudentMapper;
import edu.hncj.ssm.pojo.Student;
import edu.hncj.ssm.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class StudentServiceImpl implements StudentService {

    private StudentMapper studentMapper;

    @Autowired
    public StudentServiceImpl(StudentMapper studentMapper) {
        this.studentMapper = studentMapper;
    }


    @Override
    public void delete(Integer id) {
        studentMapper.delete(id);
    }

    @Override
    public void update(Student student) {
        studentMapper.update(student);
    }

    @Override
    public Student findById(Integer id) {
        return studentMapper.findById(id);
    }

    @Override
    public void save(Student employee) {
        studentMapper.save(employee);
    }

    @Override
    public List<Student> lists() {
        return studentMapper.lists();
    }
}

4.4 创建StudentController类

在edu.hncj.ssm.controller下创建StudentController

代码语言:javascript
复制
package edu.hncj.ssm.controller;

import edu.hncj.ssm.pojo.Student;
import edu.hncj.ssm.service.StudentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("student")
public class StudentController {

    private static final Logger log = LoggerFactory.getLogger(StudentController.class);


    private StudentService service;

    @Value("G:\\ideaproject\\chapter15\\src\\main\\webapp\\upload")
    private String realpath;

    @Autowired
    public StudentController(StudentService employeeService) {
        this.service = employeeService;
    }


    /**
     * 删除学生信息
     * @param id
     * @return
     */
    @RequestMapping("delete")
    public String delete(Integer id){
        log.debug("删除的学生id: {}",id);
        //1.删除数据
        String photo = service.findById(id).getPhoto();
        service.delete(id);
        //2.删除头像
        File file = new File(realpath, photo);
        if (file.exists()) file.delete();
        return "redirect:/student/lists";//跳转到学生列表
    }

    /**
     * 更新学生信息
     *
     * @param student
     * @param img
     * @return
     */
    @RequestMapping("update")
    public String update(Student student, MultipartFile img) throws IOException {

        log.debug("更新之后学生信息: id:{},姓名:{},成绩:{}", student.getId(), student.getName(), student.getScore());
        //1.判断是否更新头像
        boolean notEmpty = !img.isEmpty();
        log.debug("是否更新头像: {}", notEmpty);
        if (notEmpty) {
            //1.删除老的头像 根据id查询原始头像
            String oldPhoto = service.findById(student.getId()).getPhoto();
            File file = new File(realpath, oldPhoto);
            if (file.exists()) file.delete();//删除文件
            //2.处理新的头像上传
            String originalFilename = img.getOriginalFilename();
            String newFileName = uploadPhoto(img, originalFilename);
            //3.修改学生新的头像名称
            student.setPhoto(newFileName);
        }
        //2.没有更新头像直接更新基本信息
        service.update(student);
        return "redirect:/student/lists";//更新成功,跳转到学生列表
    }

    //上传头像方法
    private String uploadPhoto(MultipartFile img, String originalFilename) throws IOException {
        String fileNamePrefix = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        String fileNameSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName = fileNamePrefix + fileNameSuffix;
        img.transferTo(new File(realpath, newFileName));
        return newFileName;
    }

    /**
     * 根据id查询学生详细信息
     *
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("detail")
    public String detail(Integer id, Model model) {
        log.debug("当前查询学生id: {}", id);
        //1.根据id查询一个
        Student student = service.findById(id);
        model.addAttribute("student", student);
        return "updateStu";//跳转到更新页面
    }

    /**
     * 保存学生信息
     * 文件上传: 1.表单提交方式必须是post  2.表单enctype属性必须为 multipart/form-data
     *
     * @return
     */
    @RequestMapping("save")
    public String save(Student employee, MultipartFile img) throws IOException {
        log.debug("姓名:{}, 成绩:{} ", employee.getName(), employee.getScore());
        String originalFilename = img.getOriginalFilename();
        log.debug("头像名称: {}", originalFilename);
        log.debug("头像大小: {}", img.getSize());
        log.debug("上传的路径: {}", realpath);

        //1.处理头像的上传&修改文件名称
        String newFileName = uploadPhoto(img, originalFilename);
        //2.保存学生信息
        employee.setPhoto(newFileName);//保存头像名字
        service.save(employee);
        return "redirect:/student/lists";//保存成功跳转到列表页面
    }

    /**
     * 学生列表
     *
     * @return
     */
    @RequestMapping("lists")
    public String lists(Model model) {
        log.debug("查询所有学生信息");
        List<Student> studentlist = service.lists();
        model.addAttribute("studentlist", studentlist);
        return "studentlist";
    }

    /**
     * 添加学生列表
     * @return
     */
    @RequestMapping("addStu")
    public String addStu(Model model) {
        log.debug("新增学生信息");
        return "addStu";
    }
}

4.5 创建studentlist.html视图

代码语言:javascript
复制
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
	<head>
		<title>studentlist</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}" />
	</head>
	<body>
		<div id="wrap">
			<div id="top_content"> 
				<div id="header">
					<div id="rightheader">
						<p>
							<a th:if="${session.user!=null}" th:href="@{/user/logout}">安全退出</a>
							<a th:if="${session.user==null}" th:href="@{/user/login}">点我登录</a>
						</p>
					</div>
					<div id="topheader">
						<h1 id="title">
							<a href="#">主页</a>
						</h1>
					</div>
					<div id="navigation">
					</div>
				</div>
				<div id="content">
					<p id="whereami">
					</p>
					<h1>欢迎 
						<span th:if="${session.user!=null}" th:text="${session.user.username}"></span>
						<span th:if="${session.user==null}" >游客</span>!
					</h1>
					<table class="table">
						<tr class="table_header">
							<td>编号</td><td>姓名</td><td>头像</td><td>成绩</td><td>操作</td>
						</tr>
						<tr th:each="student,state:${studentlist}"  th:class="${state.odd?'row1':'row2'}">
							<td><span th:text="${student.id}"></span></td>
							<td><span th:text="${student.name}"></span></td>
							<td><img th:src="@{/upload/}+${student.photo}" width="60"></td>
							<td><span th:text="${student.score}"></span></td>
							<td>
								<a href="javascript:;" th:onclick="'deleteStudent('+${student.id}+')'">删除</a>
								<a th:href="@{/student/detail(id=${student.id})}">更新</a>
							</td>
						</tr>
						<script>
							function deleteStudent(id){
								console.log(id);
								if(window.confirm('确定要删除这条记录吗?')){
									location.href='[[@{/student/delete?id=}]]'+id;
								}
							}
						</script>
					</table>
					<p>
						<input type="button" class="button" value="添加" onclick="addStu()"/>
						<script>
							function addStu(){
								location.href = '[[@{/student/addStu}]]';
							}
						</script>
					</p>
				</div>
			</div>
			<div id="footer">
				<div id="footer_bg">
					123@qq.com
				</div>
			</div>
		</div>
	</body>
</html>

4.6 创建addStu.html视图

代码语言:javascript
复制
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymealf.org">
	<head>
		<title>添加学生信息</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<link rel="stylesheet" type="text/css"
			href="/css/style.css" />
	</head>

	<body>
		<div id="wrap">
			<div id="top_content">
					<div id="header">
						<div id="rightheader">
						</div>
						<div id="topheader">
							<h1 id="title">
								<a href="#">main</a>
							</h1>
						</div>
						<div id="navigation">
						</div>
					</div>
				<div id="content">
					<p id="whereami"></p>
					<h1>添加学生信息:</h1>
					<form th:action="@{/student/save}" method="post" enctype="multipart/form-data">
						<table cellpadding="0" cellspacing="0" border="0"
							class="form_table">
							<tr>
								<td valign="middle" align="right">姓名:</td>
								<td valign="middle" align="left">
									<input type="text" class="inputgri" name="name" />
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">头像:</td>
								<td valign="middle" align="left">
									<input type="file" width="" name="img" />
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">成绩:</td>
								<td valign="middle" align="left">
									<input type="text" class="inputgri" name="score" />
								</td>
							</tr>
						</table>
						<p>
							<input type="submit" class="button" value="确认添加" />
							<input type="submit" class="button" value="返回列表" />
						</p>
					</form>
				</div>
			</div>
			<div id="footer">
				<div id="footer_bg">
					123@qq.com
				</div>
			</div>
		</div>
	</body>
</html>

4.7 创建updateStu.html视图

代码语言:javascript
复制
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
	<head>
		<title>更新学生信息</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<link rel="stylesheet" type="text/css"
			th:href="@{/css/style.css}" />
	</head>

	<body>
		<div id="wrap">
			<div id="top_content">
					<div id="header">
						<div id="rightheader">
						</div>
						<div id="topheader">
							<h1 id="title"><a href="#">main</a></h1>
						</div>
						<div id="navigation">
						</div>
					</div>
				<div id="content">
					<p id="whereami"></p>
					<h1>更新学生信息:</h1>
					<form th:action="@{/student/update}" method="post" enctype="multipart/form-data">
						<table cellpadding="0" cellspacing="0" border="0"
							class="form_table">
							<tr>
								<td valign="middle" align="right">编号:</td>
								<td valign="middle" align="left">
									<span th:text="${student.id}"></span>
									<input type="hidden" name="id" th:value="${student.id}">
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">姓名:</td>
								<td valign="middle" align="left">
									<input type="text" class="inputgri" name="name" th:value="${student.name}"/>
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">当前头像:</td>
								<td valign="middle" align="left">
									<img th:src="@{/upload/}+${student.photo}" width="60">
									<input type="hidden" th:value="${student.photo}" name="photo">
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">选择新头像:</td>
								<td valign="middle" align="left">
									<input type="file" name="img" />
								</td>
							</tr>
							<tr>
								<td valign="middle" align="right">成绩:</td>
								<td valign="middle" align="left">
									<input type="text" class="inputgri" name="score" th:value="${student.score}"/>
								</td>
							</tr>
						</table>
						<p>
							<input type="submit" class="button" value="更新" />
							<input type="button" class="button" value="返回列表" onclick="lists()" />
							<script>
								function lists(){
									location.href = '[[@{/student/lists}]]';
								}
							</script>

						</p>
					</form>
				</div>
			</div>
			<div id="footer">
				<div id="footer_bg">
					123@qq.com
				</div>
			</div>
		</div>
	</body>
</html>

5 单元测试

目前为止,项目工程结构为:

运行项目,访问

代码语言:javascript
复制
http://localhost:8080/user/login

进入登录页面,内容如下:

点击还没有账号,立即注册,如下:

注册完成后,跳到到登录页面,登录成功后,跳到到学生列表页

点击添加,可以添加学生信息

添加完学生信息后,返回学生列表页

点击更新后,跳转到更新页面

点击删除后,弹出确认框

删除后,跳转回学生列表页

点击安全退出后,由于拦截器的作用,跳转到登录页面

6 本章小节

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SSM整合-基于IDEA社区版和Maven-案例入门
  • 1 系统功能概述
  • 2 数据库设计
    • 2.1在ssm数据库下创建user表:
      • 2.2 在ssm数据库下创建employee表
      • 3 用户登录模块
        • 3.1 创建User实体类:
          • 3.2 创建UserMapper接口:
            • 3.3 创建service接口和实现类:
              • 3.4 创建二维码生成类
                • 3.5 创建UserController类:
                  • 3.6 创建login.html视图
                    • 3.7 创建register.html视图
                      • 3.8 创建style.css
                        • 3.9 创建拦截器LoginHandlerInterceptor
                        • 4 用户管理模块
                          • 4.1 创建Student实体类
                            • 4.2 创建StudentMapper接口
                              • 4.3 创建StudentService接口和实现类StudentServiceImpl
                                • 4.4 创建StudentController类
                                  • 4.5 创建studentlist.html视图
                                    • 4.6 创建addStu.html视图
                                      • 4.7 创建updateStu.html视图
                                      • 5 单元测试
                                      • 6 本章小节
                                      相关产品与服务
                                      数据库
                                      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档