JavaEE课程设计(项目详细设计)

news2024/11/25 4:39:40

目录

项目文件组织结构

springbootschemaApplication

dao

controller 

application.yml

entity 

annotation 

interceptor 

config 


项目文件组织结构

这是后端部分的源码结构图

springbootschemaApplication

springbootschemaApplication是整个项目的入口

package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = {"com.dao"})
public class SpringbootSchemaApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootSchemaApplication.class, args);
	}

}

 

@SpringBootApplication
说明这是一个springboot应用


@MapperScan(basePackages = {"com.dao"})

这个是说明他要扫描dao包

dao

dao包里声明了一些方法,service层就可以调用这些方法。

controller 

 

controller是MVC中的C层,controller又调用了service层,service分为接口和实现类

 

service层又调用了dao层

application.yml

 application.yml也是一个springboot启动后会自动加载的配置文件,这里定义了mybatis-plus的一些配置,classpath*指的是

这俩 

 

 

为什么说是折俩能看这个项目结构中说明了源文件、测试文件、资源文件和项目启动后的target文件的目录位置。

 application.yml这里的mapper指的就是下面这个

 

entity 

 

这里用了一些和数据库一一对应的实体类

# Tomcat
server:
    tomcat:
        uri-encoding: UTF-8
    port: 8080
    servlet:
        context-path: /springbootjlvpC

spring:
    datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/springbootjlvpC?useUnicode=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
        username: root
        password: 123456
    servlet:
      multipart:
        max-file-size: 10MB
        max-request-size: 10MB
    resources:
      static-locations: classpath:static/,file:static/

#mybatis
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.entity
  global-config:
    #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 1
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 2
    #驼峰下划线转换
    db-column-underline: true
    #刷新mapper 调试神器
    refresh-mapper: true
    #逻辑删除配置
    logic-delete-value: -1
    logic-not-delete-value: 0
    #自定义SQL注入器
    sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    call-setters-on-nulls: true
    #springboot 项目mybatis plus 设置 jdbcTypeForNull (oracle数据库需配置JdbcType.NULL, 默认是Other)
    jdbc-type-for-null: 'null' 

annotation 

 

package com.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 登录用户信息
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface APPLoginUser {

}

 

package com.annotation;

import java.lang.annotation.*;

/**
 * 忽略Token验证
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IgnoreAuth {

}
package com.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 登录用户信息
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {

}

interceptor 

这里可以体现出面向切面编程的思想,所有的方法都要经过这里过滤 

package com.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.annotation.IgnoreAuth;
import com.entity.EIException;
import com.entity.TokenEntity;
import com.service.TokenService;
import com.utils.R;

/**
 * 权限(Token)验证
 */
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    public static final String LOGIN_TOKEN_KEY = "Token";

    @Autowired
    private TokenService tokenService;
    
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

		//支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }

        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        
        /**
         * 不需要验证权限的方法直接放过
         */
        if(annotation!=null) {
        	return true;
        }
        
        TokenEntity tokenEntity = null;
        if(StringUtils.isNotBlank(token)) {
        	tokenEntity = tokenService.getTokenEntity(token);
        }
        
        if(tokenEntity != null) {
        	request.getSession().setAttribute("userId", tokenEntity.getUserid());
        	request.getSession().setAttribute("role", tokenEntity.getRole());
        	request.getSession().setAttribute("tableName", tokenEntity.getTablename());
        	request.getSession().setAttribute("username", tokenEntity.getUsername());
        	return true;
        }
        
		PrintWriter writer = null;
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		try {
		    writer = response.getWriter();
		    writer.print(JSONObject.toJSONString(R.error(401, "请先登录")));
		} finally {
		    if(writer != null){
		        writer.close();
		    }
		}
//				throw new EIException("请先登录", 401);
		return false;
    }
}

config 


package com.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.mapper.MetaObjectHandler;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;

/**
 * mybatis-plus配置
 * @author yangliyuan
 * @date 2019年6月25日 上午10:41:15
 */
@Configuration
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    
}

Configuration经典的springboot的约定大于配置思想,这里就配置了一个当数据多的时候分页。约定大于配置就是我们不配置就用默认的springboot的配置,我们配置了就覆盖掉默认的。

package com.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.interceptor.AuthorizationInterceptor;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport{
	
	@Bean
    public AuthorizationInterceptor getAuthorizationInterceptor() {
        return new AuthorizationInterceptor();
    }
	
	@Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getAuthorizationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");
        super.addInterceptors(registry);
	}
	
	/**
	 * springboot 2.0配置WebMvcConfigurationSupport之后,会导致默认配置被覆盖,要访问静态资源需要重写addResourceHandlers方法
	 */
	@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/**")
        .addResourceLocations("classpath:/resources/")
        .addResourceLocations("classpath:/static/")
        .addResourceLocations("classpath:/admin/")
        .addResourceLocations("classpath:/front/")
        .addResourceLocations("classpath:/public/");
		super.addResourceHandlers(registry);
    }
}

权限验证的配置,前面提到一个面向切面(中断)的思维,从我一个小白的角度看就是一个过滤,说明了他要过滤谁怎么过滤。对什么验证对什么不验证。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/667054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI热门垂直领域大模型盘点(附论文)

上回分享了一些通用大模型的使用感受,今天咱们就来聊聊垂直领域大模型,照旧附上论文资料,同学们自取哈! 其实照目前的趋势来看,垂直领域大模型的未来发展是要比通用大模型好的,一是通用大模型有GPT4这座难…

Java手动编码实现与k8s交互式shell

前言 要手动编码,和k8s做shell交互,我们需要弄清以下两个问题: 1、Java如何与k8s做shell交互 2、前端界面如何与Java后台交互 3、多个用户并发访问如何实现 问题1: k8s官方提供了各种语言的KubernetesAPI,对于Ja…

用AI修复郭德纲远古相声;小红书爆款文案Prompt模板;用AI经营一家三明治店;AI将实现80%编程 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 B站UP主使用AI修复郭德纲远古相声,10天播放近70万 B站UP主 野老相声-风景-4K修复 使用了AI换脸技术,对郭德纲、…

【ArcGIS Pro二次开发】(41):勘测定界txt文件转数据库(批量)

在规划工作中有时候会收到一种带坐标点的txt文件: 上网查了一下资料,这是根据《勘测定界界址点坐标交换格式》制作的固定格式文件。 其中包含了坐标系、精度、地块编号、地块名称、坐标点等信息。 这个工具的目的就是将TXT格式坐标批量转换为数据库文件…

生物群落(生态)数据统计分析与绘图

R 语言作的开源、自由、免费等特点使其广泛应用于生物群落数据统计分析。生物群落数据多样而复杂,涉及众多统计分析方法。以生物群落数据分析中的最常用的统计方法回归和混合效应模型、多元统计分析技术及结构方程等数量分析方法为主线,通过多个来自经典…

一些WEB测试方法

ladys and 乡亲们,long time no see,发个笔记:) 首先,WEB是咋组成的 Web应用程序一般是B/S模式,一个Web应用程序是由完成特定任务的各种Web组件(web components)构成的并通过Web将服务展示给外界&#xff…

最喜爱的编程语言——Python

一、编程语言发展 编程语言(programming language)可以简单的理解为一种计算机和人都能识别的语言。一种能够让程序员准确地定义计算机所需数据的计算机语言,并精确地定义在不同情况下所应当采取的行动。 编程语言处在不断的发展和变化中&…

上海亚商投顾:沪指延续调整 机器人概念股掀涨停潮

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪 大小指数今日略显分化,沪指全天震荡调整,深成指、创业板指则拉升翻红。机器人概念股掀涨停…

手把手教你使用抖音DOU+创作个性化视频!

抖音DOU是抖音推出的一项全新功能,旨在为用户提供更加个性化、丰富多彩的内容创作和交流体验。DOU提供了一系列强大的创作工具,包括音频剪辑、特效滤镜、场景转换、字幕编辑等,让用户可以轻松地将自己的创意通过视频分享到抖音平台上来。下面…

数值分析第四章节 用Python实现数值积分与数值微分

参考书籍:数值分析 第五版 李庆杨 王能超 易大义编 第4章 数值积分与数值微分 文章声明:如有发现错误,欢迎批评指正 文章目录 梯形公式矩形公式辛普森公式柯特斯公式复合梯形公式复合辛普森公式 4.1数值积分概论 4.1.1数值积分基本思想 使用某…

【Vue全家桶高仿小米商城】——(四)项目基础架构

第四章:项目基础架构 此章节全力讲解前端基本项目架构,通过此章节可搭建一个通用性的前端架构,内容涵盖跨域方案、路由封装、错误拦截等。 文章目录 第四章:项目基础架构一、前端跨域解决什么是前端跨域?怎么解决前端…

将h5项目转成uniapp小程序

打开微信开发者工具&#xff0c;新建项目&#xff1b;pages下index文件中index.wxml文件打开内容全删除&#xff1b;写入<web-view srchttp://域名.com/></web-view>&#xff1b;编译&#xff0c;成功在小程序中展示&#xff1b;其后&#xff0c;正常按照小程序流程…

scp命令及后台运行

将项目从一个服务器迁移到另外一个服务器的时候 当项目很大的时候 可以用到如下 1、scp -r 本地项目路径 需要迁移服务器的IP:/存放路径 scp -r /u01/media/Disk1/ 192.168.1.31:/u01/media/ reverse mapping checking getaddrinfo for bogon failed - POSSIBLE BREAK-IN ATTEM…

算法篇——动态规划 01背包问题 (js版)——更新新题

416. 分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 链接&#xff1a;力扣 解题思路&#xff1a; 这道题看似是比较简单的背包问题&#xff1a; 首先可以通过判断数组和是否是…

【ZenUML】时序图之ZenUML详解

时序图 序列图是一种交互图&#xff0c;显示进程如何彼此操作以及顺序。 Mermaid可以使用ZenUML渲染序列图。请注意&#xff0c;ZenUML使用的语法与mermaid中的原始序列图不同。 目前&#xff0c;最新版本mermaid v10.2.3 暂时不单独支持zenuml语法,需要配合mermaid-zenuml一…

动态规划_可视化校园导航Floyd算法应用

目录 引言 图片展示 视频展示 针对校园导航问题的分析 关键技术和算法介绍 详细介绍&#xff1a;算法的实现 总结 代码 附件&#xff1a;Map.png 引言 本文主要通过详细的程序打印和作者的推理过程&#xff0c;描述作者对Floyd算法的理解&#xff0c;阐述其中的动态规划思想是如…

突然发现CSDN变得不一样了【建议】【活动】

突然发现CSDN变得不一样了【活动】 前言推荐突然发现CSDN变得不一样了关于上传代码包关于上传视频关于运行代码关于插入代码1关于插入代码2关于社区的建立关于社区的管理关于此次活动的评选关于排行突然发现说明一下关于我 最后 前言 2023-6-19 23:34:04 本文章仅用于参加 20…

【Python 随练】年龄计算问题

题目&#xff1a; 有 5 个人坐在一起&#xff0c;问第五个人多少岁&#xff1f;他说比第 4 个人大 2 岁。问第 4 个人岁数&#xff0c;他说比第3 个人大 2 岁。问第三个人&#xff0c;又说比第 2 人大两岁。问第 2 个人&#xff0c;说比第一个人大两岁。最后问第一个人&#x…

C++基础(8)——类和对象(6)

前言 本文主要介绍了C中多态的基本知识 4.7.1&#xff1a;多态的基本概念和原理剖析 1&#xff1a;基本概念 静态多态&#xff1a;函数重载、运算符重载 动态多态&#xff1a;派生类和虚函数实现运行时多态 静态多态在编译阶段确定函数地址&#xff1b;动态多态在运行阶段…

微信小程序uniapp+springboot实现小程序服务通知

微信小程序uniappspringboot实现小程序服务通知 1. 实现效果 2. 模板选用及字段类型判断 2.1 开通订阅消息,并选用模板 如果点击订阅消息让开启消息订阅开启后就可以出现以下页面,我本次使用的模板是月卡到期提醒模板,点击选用即可 2.2 查看模板字段类型 TemplateId后续会使用…