从零快速搭建一个SpringBoot Web项目

从零快速搭建一个SpringBoot Web项目

环境:

  1. IDEA+Navicat+Jdk1.8+Mysql5.7
  2. SpringBoot+Thymeleaf+SpringData-JPA+apache-shiro

目录

从零快速搭建一个SpringBoot Web项目 

一、新建一个SpringBoot项目 

1.1 选择新增:File->New->Project 

1.2 选择Spring Initializr,指定JDK版本,直接下一步 

1.3填写项目相关信息,然后下一步 

1.4 选择Web,勾选中间Spring Web,然后下一步 

1.5 选择代码存放位置(可默认),点击完成。 

1.6 等待代码下载完成,代码结构如下: 

1.7 至此,已经可以直接运行项目(默认端口8080,项目访问路径为/)。 

1.8 将项目端口改为8888,项目名称改为demo。新增application.yml(也可以直接在application.properties里面配置,主要取决于个人习惯) 

1.9 添加HelloController测试Web

1.10 测试项目,启动应用,使用浏览器访问:127.0.0.1:8888/demo/hello

二、 集成前端框架thymeleaf框架(或freemarker) 

2.1 在pom.xml中添加thymeleaf依赖 

2.2 添加UserController用于测试Thymeleaf

2.3 在resources/templates添加user.html

2.4 测试Thymeleaf 

三、 集成SpringDataJPA(或Mybatis-->MybatisPlus) 

3.1 在pom.xml中引入SpringDataJPA相关依赖 

3.2 配置数据源

3.3 完成User、UserRepository、UserService、UserServiceImpl 

3.3.1新增类domain.User

3.3.2新增接口repository.UserRepository

3.3.3新增接口service.UserService

3.3.4新增类service.impl.UserServiceImpl

3.4 在UserController中使用UserService 

3.5 改造user.html,显示用户列表 

3.6 集成效果查看 

四、 安全框架Apache Shiro(或SpringScerity) 

4.1 在pom.xml中添加Apache Shiro依赖

4.2 配置CustomRealm和ShiroConfig

4.3 添加管理界面admin.html

4.4 测试集成效果 

4.5 其他优化

一、新建一个SpringBoot项目

1.1 选择新增:File->New->Project

1.2 选择Spring Initializr,指定JDK版本,直接下一步

1.3填写项目相关信息,然后下一步

1.4 选择Web,勾选中间Spring Web,然后下一步

1.5 选择代码存放位置(可默认),点击完成。

1.6 等待代码下载完成,代码结构如下:

1.7 至此,已经可以直接运行项目(默认端口8080,项目访问路径为/)。

1.8 将项目端口改为8888,项目名称改为demo。新增application.yml(也可以直接在application.properties里面配置,主要取决于个人习惯)

配置内容如下:

server:
  port: 8888
  servlet:
    context-path: /demo

1.9 添加HelloController测试Web,代码如下:

package com.oyc.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description: Hello测试控制器
 * @Author oyc
 * @Date 2020/12/1 11:26 下午
 */
@RestController
@RequestMapping("hello")
public class HelloController {

    @GetMapping
    public String hello(){
        return "Hello World";
    }
}

1.10 测试项目,启动应用,使用浏览器访问:127.0.0.1:8888/demo/hello,结果如下:

二、集成前端框架thymeleaf框架(或freemarker

2.1 在pom.xml中添加thymeleaf依赖

<!--thymeleaf 前端框架-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2.2 添加UserController用于测试Thymeleaf,代码如下:

package com.oyc.demo.controller;

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

/**
 * @Description:用户控制器
 * @Author oyc
 * @Date 2020/12/1 11:26 下午
 */
@Controller
@RequestMapping("user")
public class UserController {

    @GetMapping
    public String user(Model model) {
        model.addAttribute("title", "欢迎来到用户界面");
        return "user";
    }
}

2.3 在resources/templates添加user.html,代码如下:

<!DOCTYPE html>
<html lang="en" xmlns="http//www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户</title>
</head>
<body>
<h2>用户管理</h2>
<h2 th:text="${title}"></h2>
</body>
</html>

2.4 测试Thymeleaf

启动项目,打开浏览器,访问:127.0.0.1:8888/demo/user

三、集成SpringDataJPA(或Mybatis-->MybatisPlus)

3.1 在pom.xml中引入SpringDataJPA相关依赖

<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- druid数据库连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.9</version>
</dependency>
<!-- mybatis-plus https://mvnrepository.com/artifact/com.baomidou/mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.2</version>
</dependency>
<!--lombok 可以为我们生产getter、setter、构造方法、toString方法等-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.18</version>
    <scope>provided</scope>
</dependency>

3.2 配置数据源

spring:
  datasource:
    url: jdbc:mysql://146.56.192.87:3306/oyc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
    username: oyc
    password: 111111
    driver-class-name: com.mysql.cj.jdbc.Driver
    ###  数据源类别
    type: com.alibaba.druid.pool.DruidDataSource
    ### 初始化大小,最小,最大
    initialSize: 5
    minIdle: 5
    maxActive: 20
    ### 配置获取连接等待超时的时间,单位是毫秒
    maxWait: 60000
    ### 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    ### 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    ### 打开PSCache,并且指定每个连接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    ### 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    ### 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

3.3 完成User、UserRepository、UserService、UserServiceImpl

3.3.1新增类domain.User,代码如下:

package com.oyc.demo.domain;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

/**
 * @Description:
 * @Author oyc
 * @Date 2020/12/2 12:23 上午
 */
@Data
@Entity
@Table(name = "user")
public class User implements Serializable {
    /**
     * 用户id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    /**
     * 用户名称
     */
    private String name;

    /**
     * 账号
     */
    private String account;

    /**
     * 密码
     */
    private String password;
}

3.4.2新增接口repository.UserRepository,代码如下:

package com.oyc.demo.repository;

import com.oyc.demo.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import java.util.List;

/**
 * @ClassName UserRepository
 * @Description 用户JPA接口类,继承JPA的JpaRepository,利用Spring Data JPA 的JpaRepository实现数据的操作
 * 继承JpaRepository接口 <实体类, 主键类型> JPA根据实体类的类名去对应表名(可以使用@Entity的name属性?@Table进行修改)
 * @Author oyc
 * @Date 2020/12/2 11:26
 * @Version
 */
public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor {
    /**
     * 根据用户名称查询用户
     *
     * @param name 用户名称
     * @return
     */
    List<User> findByName(String name);

    /**
     * 根据用户账号查询用户
     *
     * @param account 用户账号
     * @return
     */
    User findByAccount(String account);
}

3.4.3新增接口service.UserService,代码如下:

package com.oyc.demo.service;

import com.oyc.demo.domain.User;

import java.util.List;

/**
 * @Description: 用户服务类接口
 * @Author oyc
 * @Date 2020/12/2 12:24 上午
 */
public interface UserService {
    /**
     * 根据id获取用户
     *
     * @return
     */
    User findById(Integer uId);

    /**
     * 用户列表
     *
     * @return
     */
    List<User> findAll();

    /**
     * 根据用户名称查询用户
     *
     * @param name 用户名称
     * @return
     */
    List<User> findByName(String name);

    /**
     * 根据用户账号查询用户
     *
     * @param account 用户账号
     * @return
     */
    User findByAccount(String account);


    /**
     * 删除用户
     *
     * @param uId
     */
    void deleteById(Integer uId);

    /**
     * 删除用户
     *
     * @param user
     */
    void delete(User user);
}

3.4.4新增类service.impl.UserServiceImpl,代码如下:

package com.oyc.demo.service.impl;

import com.oyc.demo.domain.User;
import com.oyc.demo.repository.UserRepository;
import com.oyc.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Description:
 * @Author oyc
 * @Date 2020/12/2 12:24 上午
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;


    @Override
    public User findById(Integer uId) {
        return userRepository.getOne(uId);
    }

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

    @Override
    public List<User> findByName(String name) {
        return userRepository.findByName(name);
    }

    @Override
    public User findByAccount(String account) {
        return userRepository.findByAccount(account);
    }

    @Override
    public void deleteById(Integer uId) {
        userRepository.deleteById(uId);
    }

    @Override
    public void delete(User user) {
        userRepository.delete(user);
    }

}

3.5 在UserController中使用UserService

添加:

@Autowired
private UserService userService;

model.addAttribute("userList", userService.list());

UserController的整体代码如下:

package com.oyc.demo.controller;

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

/**
 * @Description:用户控制器
 * @Author oyc
 * @Date 2020/12/1 11:26 下午
 */
@Controller
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public String user(Model model) {
        model.addAttribute("title", "欢迎来到用户界面");
        model.addAttribute("userList", userService.findAll());
        return "user";
    }
}

3.6 改造user.html,显示用户列表

添加代码:

<table>
    <tr>
        <th>id</td>
        <th>用户名</td>
    </tr>
    <tr th:each="user : ${userList}">
        <td th:text="${user.id}"></td>
        <td th:text="${user.name}"></td>
    </tr>
</table>

3.7 集成效果查看

启动项目,打开浏览器,访问:127.0.0.1:8888/demo/user,效果如下:

三、安全框架Apache Shiro(或SpringScerity)

4.1 在pom.xml中添加Apache Shiro依赖,配置如下:

<!--shiro 安全框架 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
</dependency>

4.2 配置CustomRealm和ShiroConfig

CustomRealm代码如下:

package com.oyc.demo.config;

import com.oyc.demo.domain.User;
import com.oyc.demo.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @ClassName CustomRealm
 * @Description 自定义用户认证授权器
 * @Author oyc
 * @Date 2020/12/2 14:07
 * @Version
 */
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    /**
     * 鉴权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //根据用户名去数据库查询用户信息
        User user = userService.findByAccount(name);
        if(user == null){
            return null;
        }
        // 添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //添加角色
        simpleAuthorizationInfo.addRole("admin");
        //添加权限,admin:add/user:add
        simpleAuthorizationInfo.addStringPermission("admin:add");
        return simpleAuthorizationInfo;
    }

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
        if (authenticationToken.getPrincipal() == null) {
                return null;
        }
        //获取用户信息
        String name = authenticationToken.getPrincipal().toString();
        User user = userService.findByAccount(name);
        if (user == null) {
            //这里返回后会报出对应异常
            return null;
        } else {
            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            return new SimpleAuthenticationInfo(name, user.getPassword(), getName());
        }
    }
}

ShiroConfig代码如下:

package com.oyc.demo.config;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author: oyc
 * @Date: 2020-06-02 16:11
 * @Description: shiro配置
 */
@Configuration
public class ShiroConfig {
    /**
     * Filter工厂,设置对应的过滤条件和跳转条件
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        //过滤链定义,从上向下顺序执行,一般将/**放在最为下边 ,authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        //swagger
        filterChainDefinitionMap.put("/swagger-ui.html", "anon");
        filterChainDefinitionMap.put("/swagger-resources", "anon");
        filterChainDefinitionMap.put("/swagger-resources/configuration/security", "anon");
        filterChainDefinitionMap.put("/swagger-resources/configuration/ui", "anon");
        filterChainDefinitionMap.put("/v2/api-docs", "anon");
        filterChainDefinitionMap.put("/webjars/springfox-swagger-ui/**", "anon");
        //对所有用户认证
        filterChainDefinitionMap.put("/**", "authc");
        //未登录,重定向到登录页面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        filterChainDefinitionMap.put("/**", "authc,user");
        //错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 将自己的验证方式加入容器
     */
    @Bean
    public CustomRealm myShiroRealm() {
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }

    /**
     * 安全管理器,配置主要是Realm的管理认证
     */
    @Bean
    public SecurityManager securityManager(CustomRealm myShiroRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(myShiroRealm);
        return securityManager;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
     *
     * @return
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}

4.3 添加管理界面admin.html,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎使用系统</title>
</head>
<body>
<h1>登录成功,欢迎使用系统</h1>
</body>
</html>

4.4 测试集成效果

启动项目,打开浏览器访问:127.0.0.1:8888/demo,可以正常访问。访问:127.0.0.1:8888/demo/admin,会先出现登录界面,输入正确的用户名和密码之后,点击登录,正常跳转到管理界面。效果如下:

欢迎界面:

登录界面:

管理界面:

4.5 其他优化

密码加密、用户角色从数据库获取(user-->user_role-->role、user-->role_menu-->menu)

未完待续

注:

源码地址: https://gitee.com/oycyqr/springboot-web-demo.git

猜你喜欢

转载自blog.csdn.net/u014553029/article/details/112593340