Spring Boot 一个Web项目的简单例子

作者: 右耳菌 | 来源:发表于2022-04-25 23:33 被阅读0次

一、前期准备工作

  1. 熟悉thymeleaf语法
  2. 熟悉spring、springMVC里面的相关操作
  3. 熟悉拦截器
  4. 熟悉springboot搭建项目过程
  5. 了解Bootstrap
  6. 准备一套web静态页面(登录页面、信息展示主页面)
  7. IDEA开发工具

二、项目整体思路

项目整体思路
1. 搭建项目并正常访问

构建一个springboot项目,并把静态资源放入到项目中

  • css、js、img等资源放入到static目录
    因为本项目使用的是cdn的方式,即在对应的html页面中对应位置插入以下内容即可
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <!-- 新 Bootstrap4 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/css/bootstrap.min.css">
    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
    <script src="https://cdn.staticfile.org/popper.js/1.12.5/umd/popper.min.js"></script>
    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
  • html等模板代码放入到template目录
    这里使用thymeleaf语法
  1. login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <title>登陆页面</title>
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <!-- 新 Bootstrap4 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/css/bootstrap.min.css">
    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
    <script src="https://cdn.staticfile.org/popper.js/1.12.5/umd/popper.min.js"></script>
    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
    <script>
        $(function(){
            $("button:contains('删除')").click(function(){
                $.post("/user/delete",{"id":this.id});
                $(this).parent().parent().remove();
            });
            $("button:contains('修改')").click(function(){
                //弹出修改窗口
                $('#myModal').modal();
                //把User对象转成json对象
                var jsonObj = JSON.parse($(this).attr("id"));
                //为修改页面进行赋值
                $('#txt_id').val(jsonObj['id']);
                $('#txt_username').val(jsonObj['username']);
                $('#txt_password').val(jsonObj['password']);
                $('#txt_name').val(jsonObj['name']);
                $('#txt_userSex').val(jsonObj['userSex']);
            });
        })
        //添加的方法
        function add() {
            //弹出新建窗口
            $('#myModal1').modal();
        }
    </script>
</head>
<body>
<div class="container">
    <table class="table table-dark table-hover">
        <thead>
            <tr>
                <th>id</th>
                <th>用户名</th>
                <th>密码</th>
                <th>真实姓名</th>
                <th>性别</th>
                <th>删除</th>
                <th>修改</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="users:${list}">
                <td th:text="${users.id}"></td>
                <td th:text="${users.username}"></td>
                <td th:text="${users.password}"></td>
                <td th:text="${users.name}"></td>
                <td th:text="${users.userSex}"></td>
                <th><button th:id="${users.id}" onclick="return confirm('你确定要删除这条数据吗?')">删除</button></th>
                <th><button th:id="${users}">修改</button></th>
            </tr>
        </tbody>
    </table>
    <button onclick="add()">添加</button>
    <!--添加页面-->
    <div class="modal fade" id="myModal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <form method="post" action="#" th:action="@{/add.do}">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title" id="myModalLabel1">添加</h4>
                    </div>
                    <div class="modal-body">
                        <div class="form-group">
                            <label for="txt_username">用户名</label>
                            <input type="text" name="username" class="form-control" placeholder="用户名">
                        </div>
                        <div class="form-group">
                            <label for="txt_password">密码</label>
                            <input type="password" name="password" class="form-control" placeholder="密码">
                        </div>
                        <div class="form-group">
                            <label for="txt_name">真实姓名</label>
                            <input type="text" name="name" class="form-control" placeholder="真实姓名">
                        </div>
                        <div class="form-group">
                            <label for="txt_userSex">性别</label>
                            <input type="text" name="userSex" class="form-control" placeholder="性别">
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭</button>
                        <input type="submit" value="保存" id="btn_submit1" class="btn btn-primary" /><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!--修改页面-->
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <form method="post" action="#" th:action="@{/update.do}">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title" id="myModalLabel">修改</h4>
                    </div>
                    <div class="modal-body">
                        <input type="text" name="id" id="txt_id" hidden="true">
                        <div class="form-group">
                            <label for="txt_username">用户名</label>
                            <input type="text" name="username" class="form-control" id="txt_username" placeholder="用户名">
                        </div>
                        <div class="form-group">
                            <label for="txt_password">密码</label>
                            <input type="password" name="password" class="form-control" id="txt_password" placeholder="密码">
                        </div>
                        <div class="form-group">
                            <label for="txt_name">真实姓名</label>
                            <input type="text" name="name" class="form-control" id="txt_name" placeholder="真实姓名">
                        </div>
                        <div class="form-group">
                            <label for="txt_userSex">性别</label>
                            <input type="text" name="userSex" class="form-control" id="txt_userSex" placeholder="性别">
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭</button>
                        <input type="submit" value="保存" id="btn_submit" class="btn btn-primary" /><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
</body>
</html>
  1. list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <title>登陆页面</title>
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <!-- 新 Bootstrap4 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/css/bootstrap.min.css">
    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
    <script src="https://cdn.staticfile.org/popper.js/1.12.5/umd/popper.min.js"></script>
    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
    <script>
        $(function(){
            $("button:contains('删除')").click(function(){
                $.post("/user/delete",{"id":this.id});
                $(this).parent().parent().remove();
            });
            $("button:contains('修改')").click(function(){
                //弹出修改窗口
                $('#myModal').modal();
                //把User对象转成json对象
                var jsonObj = JSON.parse($(this).attr("id"));
                //为修改页面进行赋值
                $('#txt_id').val(jsonObj['id']);
                $('#txt_username').val(jsonObj['username']);
                $('#txt_password').val(jsonObj['password']);
                $('#txt_name').val(jsonObj['name']);
                $('#txt_userSex').val(jsonObj['userSex']);
            });
        })
        //添加的方法
        function add() {
            //弹出新建窗口
            $('#myModal1').modal();
        }
    </script>
</head>
<body>
<div class="container">
    <table class="table table-dark table-hover">
        <thead>
            <tr>
                <th>id</th>
                <th>用户名</th>
                <th>密码</th>
                <th>真实姓名</th>
                <th>性别</th>
                <th>删除</th>
                <th>修改</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="users:${list}">
                <td th:text="${users.id}"></td>
                <td th:text="${users.username}"></td>
                <td th:text="${users.password}"></td>
                <td th:text="${users.name}"></td>
                <td th:text="${users.userSex}"></td>
                <th><button th:id="${users.id}" onclick="return confirm('你确定要删除这条数据吗?')">删除</button></th>
                <th><button th:id="${users}">修改</button></th>
            </tr>
        </tbody>
    </table>
    <button onclick="add()">添加</button>
    <!--添加页面-->
    <div class="modal fade" id="myModal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <form method="post" action="#" th:action="@{/add.do}">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title" id="myModalLabel1">添加</h4>
                    </div>
                    <div class="modal-body">
                        <div class="form-group">
                            <label for="txt_username">用户名</label>
                            <input type="text" name="username" class="form-control" placeholder="用户名">
                        </div>
                        <div class="form-group">
                            <label for="txt_password">密码</label>
                            <input type="password" name="password" class="form-control" placeholder="密码">
                        </div>
                        <div class="form-group">
                            <label for="txt_name">真实姓名</label>
                            <input type="text" name="name" class="form-control" placeholder="真实姓名">
                        </div>
                        <div class="form-group">
                            <label for="txt_userSex">性别</label>
                            <input type="text" name="userSex" class="form-control" placeholder="性别">
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭</button>
                        <input type="submit" value="保存" id="btn_submit1" class="btn btn-primary" /><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!--修改页面-->
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <form method="post" action="#" th:action="@{/update.do}">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title" id="myModalLabel">修改</h4>
                    </div>
                    <div class="modal-body">
                        <input type="text" name="id" id="txt_id" hidden="true">
                        <div class="form-group">
                            <label for="txt_username">用户名</label>
                            <input type="text" name="username" class="form-control" id="txt_username" placeholder="用户名">
                        </div>
                        <div class="form-group">
                            <label for="txt_password">密码</label>
                            <input type="password" name="password" class="form-control" id="txt_password" placeholder="密码">
                        </div>
                        <div class="form-group">
                            <label for="txt_name">真实姓名</label>
                            <input type="text" name="name" class="form-control" id="txt_name" placeholder="真实姓名">
                        </div>
                        <div class="form-group">
                            <label for="txt_userSex">性别</label>
                            <input type="text" name="userSex" class="form-control" id="txt_userSex" placeholder="性别">
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭</button>
                        <input type="submit" value="保存" id="btn_submit" class="btn btn-primary" /><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
</body>
</html>
  • 修改配置文件
  1. 修改application.properties
# 设置缓存不生效
spring.thymeleaf.cache=false
  1. 配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.lazyfennec</groupId>
    <artifactId>springboot-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 新建Controller
package cn.lazyfennec.springboot.controller;

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

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 21:53
 */
@Controller
public class UserController {
    @RequestMapping("/login")
    public String test() {
        return "login";
    }
}
  • 启动并测试是否正常


    访问测试
2. 设置主页的默认访问方式

通过修改WebMvcConfigure的默认设置来指定页面的默认访问方式

  1. 构建一个配置类,实现WebMvcConfigurer接口,重写addViewControllers方法;
  2. 添加自定义页面的默认主页映射:addViewController().setViewName()
package cn.lazyfennec.springboot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 22:28
 */
@Configuration
public class WebMvcConfigure implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login.html");
    }
}
3. 登录功能
  1. 完成登录页面的修改
  2. 完成后台编码
    a. 实体类的构建
    b. repository类以及其实现类的书写
    c. controller类的登录功能实现
  3. 完成登录失败的功能提示
  • 修改UserController类
package cn.lazyfennec.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.thymeleaf.util.StringUtils;

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 21:53
 */
@Controller
public class UserController {
    @RequestMapping("/user/login")
    public String login(String username, String password, ModelMap modelMap) {
        // 模拟登录
        if(!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)
                && "admin".equals(username) && "admin".equals(password)) {
            return "list";
        } else {
            modelMap.addAttribute("login_error", "用户名或密码错误");
            return "login";
        }
    }
}

重启测试

4. 数据展示、删除
  1. 数据展示页面的修改/添加数据删除的js代码;
  2. 后台编码
    a. controller里面加上对应的方法;
    b. repository里面加上对应的方法;
  3. 测试是否生效
  • 构建实体类User
package cn.lazyfennec.springboot.entity;

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 22:47
 */
public class User {
    private int id;
    private String username;
    private String password;
    private String name;
    private String userSex;

    public User() {
    }

    public User(int id, String username, String password, String name, String userSex) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.name = name;
        this.userSex = userSex;
    }

    public int getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

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

    public String getName() {
        return name;
    }

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

    public String getUserSex() {
        return userSex;
    }

    public void setUserSex(String userSex) {
        this.userSex = userSex;
    }
}
  • 修改UserController
package cn.lazyfennec.springboot.controller;

import cn.lazyfennec.springboot.entity.User;
import cn.lazyfennec.springboot.repository.UsersRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.thymeleaf.util.StringUtils;

import java.util.List;

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 21:53
 */
@Controller
public class UserController {

    @Autowired
    private UsersRepository usersRepository;

    @RequestMapping("/user/login")
    public String login(String username, String password, ModelMap modelMap) {
        // 模拟登录
        if(!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)
                && "admin".equals(username) && "admin".equals(password)) {
            return "redirect:/user/list";
        } else {
            modelMap.addAttribute("login_error", "用户名或密码错误");
            return "login";
        }
    }

    @RequestMapping("/user/list")
    public String findAll(ModelMap modelMap) {
        List<User> users = usersRepository.findAll();
        modelMap.addAttribute("list", users);
        return "list";
    }

    @RequestMapping("/user/delete")
    public String deleteUserById(int id) {
        int result = usersRepository.deleteUserById(id);
        return "list";
    }
}
  • 创建UsersRepository 和 UsersRepositoryImpl
package cn.lazyfennec.springboot.repository;

import cn.lazyfennec.springboot.entity.User;

import java.util.List;

public interface UsersRepository {

    List<User> findAll();

    int deleteUserById(int id);

}
package cn.lazyfennec.springboot.repository.impl;

import cn.lazyfennec.springboot.entity.User;
import cn.lazyfennec.springboot.repository.UsersRepository;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 22:50
 */
@Repository
public class UsersRepositoryImpl implements UsersRepository {

    // 模拟数据库
    static List<User> users = new ArrayList<>();

    static {
        Collections.addAll(users,
                new User(1001, "zhangsan", "123456", "张三", "男"),
                new User(1002, "lisi", "123456", "李四", "女"),
                new User(1003, "wangwu", "123456", "王五", "男"),
                new User(1004, "maliu", "123456", "马六", "女")
        );
    }

    @Override
    public List<User> findAll() {
        return users;
    }

    @Override
    public int deleteUserById(int id) {
        Iterator<User> iterator = users.iterator();
        while (iterator.hasNext()) {
            User user = iterator.next();
            if(user.getId() == id) {
                iterator.remove();
                return 1;
            }
        }
        return 0;
    }
}
  • 重启并且测试


    image.png
5. 拦截器功能
  1. 书写一个自定义拦截器类,功能就是检测是否登录
package cn.lazyfennec.springboot.intercept;

import org.springframework.web.servlet.HandlerInterceptor;

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

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 23:23
 */
public class LoginHandlerIntercept implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object username = request.getSession().getAttribute("username");
        if (username != null) {
            return true;
        } else {
            request.setAttribute("login_error", "请先登录");
            request.getRequestDispatcher("/").forward(request, response);
            return false;
        }
    }
}
  1. 在WebMvcConfigure类里重写添加拦截器的方法,并进行业务的书写
package cn.lazyfennec.springboot.config;

import cn.lazyfennec.springboot.intercept.LoginHandlerIntercept;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/4/25 22:28
 */
@Configuration
public class WebMvcConfigure implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login.html");
    }

    /**
     * 配置拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginHandlerIntercept())
                .addPathPatterns("/**")
                .excludePathPatterns("/", "/login.html", "/user/login", "/css/**", "/js/**", "/img/**");
    }
}
    @RequestMapping("/user/login")
    public String login(String username, String password, ModelMap modelMap, HttpSession session) {
        // 模拟登录
        if(!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)
                && "admin".equals(username) && "admin".equals(password)) {
            session.setAttribute("username", username); // 修改逻辑,登录后将username存到session中
            return "redirect:/user/list";
        } else {
            modelMap.addAttribute("login_error", "用户名或密码错误");
            return "login";
        }
    }
  1. 测试是否生效
    测试访问 http://localhost:8080/user/list
    测试访问 http://localhost:8080/user/list

更多知识,请点击关注查看我的主页信息哦~

相关文章

网友评论

    本文标题:Spring Boot 一个Web项目的简单例子

    本文链接:https://www.haomeiwen.com/subject/pasqyrtx.html