基于Springboot的旅游网管理系统后台

这篇具有很好参考价值的文章主要介绍了基于Springboot的旅游网管理系统后台。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 🦁 研究背景及意义

旅游作为一种经济活动,已经成为世界经济中不可或缺的一部分。旅游业的快速发展,使得旅游产品和服务的供应和需求日益增加,其中旅游网站起着至关重要的作用。近年来,随着移动互联网的普及和技术的进步,旅游网站不断创新和发展,为旅游市场的发展贡献了巨大的力量。

旅游网站的研究背景在于,通过对旅游网站的市场现状、用户需求和技术创新等方面进行研究,以更好地了解旅游网站的发展趋势和用户特征,进而为旅游网站的设计和优化提供依据,提升旅游网站的服务质量和用户体验。

旅游网站的研究意义在于,为旅游网站的设计和优化提供了思路和方法,以满足用户多样化的需求。同时,可以帮助企业更好地把握市场的机遇和挑战,提升旅游产品和服务的质量和效益。此外,随着旅游业的不断发展,旅游网站的研究也为旅游业的升级和转型提供了有价值的参考和借鉴。综上所述,旅游网站的研究具有十分重要和现实的意义。

二. 🦁 技术栈系列及主要功能

Ⅰ. 技术栈

  • Springboot
  • SpringMVC
  • MySQL
  • Mybatis-Plus
  • SpringSecurity
  • Thymeleaf
  • AdminLTE2
  • lombok、ajax、logback

Ⅱ. 主要功能

本系统基于以上技术来实现一个完善的旅游网后台管理系统,具有以下主要功能:

  • 管理员管理
  • 角色管理
  • 权限管理
  • 认证和授权
  • 产品类型管理
  • 旅游产品管理

三. 🦁 项目搭建

Ⅰ. 后端模块

该项目和平常项目差不多,后端模块按平常Springboot项目结构搭建即可,如下:
基于Springboot的旅游网管理系统后台

Ⅱ. 前端模块

在项目中,我们使用AdminLTE框架作为管理员端页面,使用自己编写的网页作为用户端页面。

tips:
AdminLTE是一款建立在bootstrap和jquery之上的开源的模板主题工具,它提供了一系列响应的、 可重复使用的组件,并内置了多个模板页面;同时自适应多种屏幕分辨率,兼容PC和移动端。通过AdminLTE,我们可以快速的创建一个响应式的Html5网站。AdminLTE框架在网页架构与设计上,有很大的辅助作用,尤其是前端架构设计师,用好AdminLTE 不但美观,而且可以免去写很大CSS与JS的工作量。

使用AdminLTE非常简单,只需要根据需求将需要的组件复制到我们的页面中即可。
基于Springboot的旅游网管理系统后台

四. 🦁 主要实现过程

主要挑几个核心部分来展开描述:

Ⅰ. 认证和授权

1. SpringSecurity配置类

众所周知,SpringSecurity遵循RBAC原则,即角色,权限,用户表,在我们添加完这个表的实体类以及一些常规CRUD操作后,就可以开始编写系统的认证和授权了。
如何来编写一个权限表?详情请看狮子前面的文章:点击

import com.lion.security.handler.MyAccessDeniedHandler;
import com.lion.security.handler.MyLoginFailureHandler;
import com.lion.security.handler.MyLoginSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)     // 开启注解-鉴权配置
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // Spring Security配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/backstage/admin_login")         //自定义表单登录
                .usernameParameter("username")          //用户名
                .passwordParameter("password")          //密码
                .loginProcessingUrl("/backstage/admin/login")   //登录提交路径,提交后执行认证逻辑
                .successHandler(new MyLoginSuccessHandler())    //登录成功跳转路径
                .failureHandler(new MyLoginFailureHandler());    //登录失败跳转路径
//          权限拦截配置
        http.authorizeRequests()
                .antMatchers("/backstage/admin/login").permitAll()      //登录不需要认证
                .antMatchers("/backstage/admin_fail").permitAll()       //登录失败不需要认证
                .antMatchers("/backstage/admin_login").permitAll()      //登录页不需要认证
                .antMatchers("/**/*.css","/**/*.js").permitAll()        //静态资源放行
                .antMatchers("/backstage/**").authenticated();          //剩下的都要认证

//        退出登录配置
        http.logout()
                .logoutUrl("/backstage/admin/logout")       //退出登录的路径
                .logoutSuccessUrl("/backstage/admin_login") //退出登录成功后跳转的页面
                .clearAuthentication(true)                  //退出成功后清除认证信息
                .invalidateHttpSession(true);                //退出成功后清除session
//            异常处理
        http.exceptionHandling()
                .accessDeniedHandler(new MyAccessDeniedHandler());  //权限不足处理器

//        关闭csrf防护
        http.csrf().disable();
//        开启跨域访问
        http.cors();

    }
//    密码加密器
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

security的配置类写法很类似,咱们分块来实现:

自定义表单登录块——>权限拦截配置——>退出登录配置——>异常处理——>关闭csrf防护——> 开启跨域访问——>密码加密器
根据自己需要来编写相应模块,详细目录如下:
基于Springboot的旅游网管理系统后台

2. 自定义逻辑认证

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lion.domain.Admin;
import com.lion.domain.Permission;
import com.lion.mapper.AdminMapper;
import com.lion.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class MyUserDetailService implements UserDetailsService {
    @Autowired
    private AdminService adminService;


    // 自定义认证逻辑
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.认证
        Admin admin = adminService.findByAdminName(username);
        if (admin == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
//        admin的状态是不可登录则报错(自定义)
        if (!admin.isStatus()){
            throw new UsernameNotFoundException("用户不可用");
        }


        // 2.授权
        List<Permission> permissions = adminService.findAllPermission(username);
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (Permission permission : permissions) {
            grantedAuthorities.add(new SimpleGrantedAuthority(permission.getPermissionDesc()));
        }


        // 3.封装为UserDetails对象
        UserDetails userDetails = User.withUsername(admin.getUsername())
                .password(admin.getPassword())
                .authorities(grantedAuthorities)
                .build();


        // 4.返回封装好的UserDetails对象
        return userDetails;
    }
}

Ⅱ. 富文本编辑器——wangEditor

在项目中,我们使用中国人开发的一个富文本编辑器——wangEditor,官网地
址:https://www.wangeditor.com/
使用步骤如下:

  1. 在前端页面中引入 wangEditor.js
  2. 在页面中加入 wangEditor 插件
  3. 编写实体类返回值

wangEditor要求上传图片的返回值必须按照它的要求,所以我们创建一个实体类,用于返回上传的结果。

import lombok.Data;

@Data
public class WangEditorResult {
    private int errno;
    private String[] data;
}

  1. 编写上传控制器,接收富文本编辑器上传的图片
@RequestMapping(value = "/upload")
    @ResponseBody
    public WangEditorResult upload(HttpServletRequest request, MultipartFile file) throws Exception {
        // 创建文件夹,存放上传文件。
        //1.设置上传文件夹的真实路径
        String realPath = ResourceUtils.getURL("classpath:").getPath()+"/static/upload/";;
        //2.判断该文件夹是否存在,如果不存在,新建文件夹
        File dir = new File(realPath);
        if (!dir.exists()){
            dir.mkdirs();
        }
        // 拿到上传文件名
        String filename = file.getOriginalFilename();
        filename = UUID.randomUUID()+filename;
        // 创建空文件
        File newFile = new File(dir, filename);
        // 将上传的文件写到空文件中
        file.transferTo(newFile);


        WangEditorResult wangEditorResult = new WangEditorResult();
        String[] data = {"/upload/"+filename};
        wangEditorResult.setErrno(0);
        wangEditorResult.setData(data);
        return wangEditorResult;
    }
  1. 在yml中配置上传文件的大小
# 上传文件
  servlet:
    multipart:
      max-file-size: 10MB # 最大单个文件
      max-request-size: 10MB # 一次请求最大上传

这样,一个编辑器就完成了!!!
基于Springboot的旅游网管理系统后台

Ⅲ. 编写AOP实现日志记录功能

1. 编写logback.xml文件

在后台代码运行的过程中,我们要对每一次操作进行日志记录,一方面通过日志可以发现代码的缺陷,另一方面可以追踪内部人员的操作记录。
SpringBoot默认使用Logback组件作为日志管理,首先在 /resources 下添加Logback配置文件 logback.xml

在这里插入代码片<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志文件的存储地址-->
    <property name="LOG_HOME" value="${catalina.base}/logs/"/>


    <!-- 控制台输出 -->
    <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志输出编码 -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
    </appender>


    <!-- 按照每天生成日志文件 -->
    <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/server.%d{yy99-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>


    <!-- 日志输出级别 -->
    <root level="info">
        <appender-ref ref="Stdout"/>
        <appender-ref ref="RollingFile"/>
    </root>
</configuration>

写法很固定,理解即可!!!

2. 编写日志记录实体类

import lombok.Data;
import java.util.Date;

@Data
public class Log {
    private String url; // 访问的路径
    private Date visitTime; // 访问时间
    private String username; // 访问者
    private String ip; // 访问ip
    private int executionTime; // 访问时长
    private String exceptionMessage; // 异常信息
}

3. 编写日志AOP类

import com.lion.bean.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Component
@Aspect
public class LogAop {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private final static Logger logger = LoggerFactory.getLogger(LogAop.class);


    /**
     * 切点,以backstage的所有controller方法作为切点
     */
    @Pointcut("execution(* com.lion.controller.backstage.*.*(..))")
    public void pointCut(){}

    /**
     * 前置通知
     * @param joinPoint
     */
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint) {
        // 记录访问时间
        Date date = new Date();
        request.setAttribute("visitTime",date);
    }

    /**
     * 后置通知
     */
    @After("pointCut()")
    public void doAfter(){
        Log log = new Log();

        Date visitTime = (Date) request.getAttribute("visitTime"); // 访问时间
        Date now = new Date();
        int executionTime = (int)(now.getTime() - visitTime.getTime()); // 访问时长
        String ip = request.getRemoteAddr(); // 访问ip
        String url = request.getRequestURI();// 访问路径
        // 拿到security中的User对象
        Object user = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user instanceof User){
            String username = ((User)user).getUsername();
            log.setUsername(username);
        }
        log.setExecutionTime(executionTime);
        log.setUrl(url);
        log.setIp(ip);
        log.setVisitTime(visitTime);


        logger.info(log.toString());
    }

    /**
     * 异常通知
     * @param ex
     */
    @AfterThrowing(pointcut = "pointCut()",throwing = "ex")
    public void afterThrowing(Throwable ex){
        Log log = new Log();


        Date visitTime = (Date) request.getAttribute("visitTime"); // 访问时间
        Date now = new Date();
        int executionTime = (int) (now.getTime() - visitTime.getTime()); // 访问时长
        String ip = request.getRemoteAddr(); // 访问ip
        String url = request.getRequestURI(); // 访问路径
        // 拿到Security中的User对象
        Object user = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user instanceof User){
            String username = ((User) user).getUsername();
            log.setUsername(username);
        }
        log.setExecutionTime(executionTime);
        log.setUrl(url);
        log.setIp(ip);
        log.setVisitTime(visitTime);


        // 异常信息
        String exMessage = ex.getMessage();
        log.setExceptionMessage(exMessage);

        logger.info(log.toString());
    }
}

以Controller为切点,编写前置通知,后置通知和异常通知,记录用户每一次操作的具体内容。

五. 🦁 实现效果

基于Springboot的旅游网管理系统后台
基于Springboot的旅游网管理系统后台

基于Springboot的旅游网管理系统后台
基于Springboot的旅游网管理系统后台
基于Springboot的旅游网管理系统后台
基于Springboot的旅游网管理系统后台
基于Springboot的旅游网管理系统后台
基于Springboot的旅游网管理系统后台
基于Springboot的旅游网管理系统后台文章来源地址https://www.toymoban.com/news/detail-440021.html

到了这里,关于基于Springboot的旅游网管理系统后台的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【python】python旅游网数据抓取分析(源码+论文)【独一无二】

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化【获取源码+商业合作】 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 每个爬虫针对特定的目标网站(去哪儿网

    2024年02月04日
    浏览(43)
  • 基于SpringBoot+Vue的旅游管理系统

    目录 前言  一、技术栈 二、系统功能介绍 登录界面 管理员功能模块 用户功能模块 三、核心代码 1、登录模块  2、文件上传模块 3、代码封装 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势,旅游网站当然也不能排除在外,

    2024年02月07日
    浏览(28)
  • 基于Springboot+thymeleaf旅游景区管理系统——LW模板

    基于java的旅游管理系统 随着我国经济的快速发展以及改革开放政策的不断完善,旅游已经成为了人们假期放松旅游的主要方式之一。我国也越来越重视旅游业的发展,出台了《关于促进全域旅游发展的指导意见》、《“十四五”文化和旅游发展规划》等政策予以扶持。旅游

    2024年02月11日
    浏览(32)
  • 基于SpringBoot+Bootstrap的旅游管理系统的设计与实现

    目录 前言  一、技术栈 二、系统功能介绍 登录模块的实现 景点信息管理界面 订票信息管理界面 用户评价管理界面 用户管理界面 景点资讯界面 系统主界面 用户注册界面 景点信息详情界面 订票信息界面 三、核心代码 1、登录模块  2、文件上传模块 3、代码封装 随着旅游业

    2024年02月07日
    浏览(29)
  • 基于java旅游网站管理系统(springboot框架)开题答辩常规问题

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年01月21日
    浏览(38)
  • 基于Java(SpringBoot框架)毕业设计作品成品(44)旅游景点旅游线路旅游网站管理系统设计与实现

    博主介绍: 《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、PPT、论文模版

    2024年02月06日
    浏览(39)
  • 基于SpringBoot的旅游路线管理系统(源码+讲解+运行)做毕设/课设均可

    【毕设者】基于SpringBoot的无忌旅游路线规划系统 (源码+讲解+帮你调试运行)做毕设课设均可 今日推荐个每个 功能都有讲解 的项目,最后评论区会附上观看地址 前后端分离 前端使用: Vue+ Element Plus 后端使用: SpringBoot + Mysql8.0 +Mybatis     分为 管理员端 和 用户端 ​     评论区

    2024年02月09日
    浏览(31)
  • 基于JAVA+Springboot+Thymeleaf前后端分离项目:旅游网站管理系统设计与实现

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩。 项目配有对应开发文档、

    2024年02月20日
    浏览(32)
  • springboot(ssm甘肃旅游管理系统 在线旅游景点管理系统 Java系统

    springboot(ssm甘肃旅游管理系统 在线旅游景点管理系统 Java系统 开发语言:Java 框架:ssm/springboot + vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.7(或8.0) 数据库工具:Navicat 开发软件:eclipse//idea 依赖管理包:Maven 如需了解更多代码细节或修改代码功能界面,本人都

    2024年01月18日
    浏览(45)
  • springboot(ssm旅游信息管理系统 在线旅游系统 Java系统

    springboot(ssm旅游信息管理系统 在线旅游系统 Java系统 开发语言:Java 框架:ssm/springboot + vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.7(或8.0) 数据库工具:Navicat 开发软件:eclipse//idea 依赖管理包:Maven 如需了解更多代码细节或修改代码功能界面,本人都能提供技

    2024年01月19日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包