spring boot 后端控制controller重复提交

前端转AI全栈:Java后端学习路径与Spring Boot实践指南 面向对象编程(OOP)是一种以对象为核心的程序设计范式,通过封装、继承和多态三大特性构建模块化、可复用的代码结构。其核心原理在于将数据与操作数据的方法绑定为对象,从而模拟现实世界实体。在工程实践中,OOP极大地提升了代码的可维护性和扩展性,是构建大型复杂系统的基石。在Java生态中,这一理念与Spring Boot框架深度结合,使得开发者能够快速搭建稳健的企业级后端服务。随着AI应用开发热潮的兴起,掌握Java后端技术成为实现AI全栈能力的关键一环,开发者可以运用Spring Boot高效构建RESTful 阅读详情

1.添加依赖

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

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>29.0-jre</version>
</dependency>

2.定义一个接口

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

/**
 * 定义一个注解
 * @apiNote @Target(ElementType.METHOD) 作用到方法上
 * @apiNote @Retention(RetentionPolicy.RUNTIME) 只有运行时有效
 * @author zhouzhaodong
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {

}

3.定义一个切面

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 自定义一个切面类,利用aspect实现切入所有方法
 *
 * @author zhouzhaodong
 */
@Aspect
@Configuration
public class NoRepeatSubmitAop {

    private final Log logger = LogFactory.getLog(getClass());

    /**
     * 重复提交判断时间为2s
     */
    private final Cache<String, Integer> cache = CacheBuilder.newBuilder().expireAfterWrite(2L, TimeUnit.SECONDS).build();

    /**
     * 调用controller包下的任意类的任意方法时均会调用此方法
     */
    //@Around("execution(* com.company.controller.*.*(..))")
    @Around("execution(* xyz.zhouzhaodong..*Controller.*(..)) && @annotation(nrs)")
    public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String sessionId = Objects.requireNonNull(RequestContextHolder.getRequestAttributes()).getSessionId();
            assert attributes != null;
            HttpServletRequest request = attributes.getRequest();
            String key = sessionId + "-" + request.getServletPath();
            // 如果缓存中有这个url视为重复提交
            if (cache.getIfPresent(key) == null) {
                Object o = pjp.proceed();
                cache.put(key, 0);
                return o;
            } else {
                logger.error("重复提交");
                return new RestMessage(888, "请勿短时间内重复操作");
            }
        } catch (Throwable e) {
            e.printStackTrace();
            logger.error("验证重复提交时出现未知异常!");
            return new RestMessage(889, "验证重复提交时出现未知异常!");
        }

    }

}

4.controller应用

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

/**
 * 测试
 * @author zhouzhaodong
 */
@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * 添加防重复提交注解
     * @return
     */
    @NoRepeatSubmit
    @RequestMapping("/one")
    public RestMessage test(){
        return new RestMessage(0, "测试通过");
    }

}

Spring Boot Controller单元测试实战:JUnit 5与Mockito完整指南 在软件工程实践中,单元测试是保障代码质量与稳定性的核心环节,它通过隔离测试单个代码单元来快速验证其逻辑正确性。其原理在于模拟依赖、控制输入并断言输出,从而构建可靠的自动化验证体系。这一技术的价值在于提升开发效率、降低回归错误风险,并促进代码的模块化设计。在Web应用开发领域,Controller层作为HTTP请求的入口,其正确性直接关系到API契约的履行与用户体验。因此,针对Controller层的单元测试成为确保应用稳定性的关键实践。本文聚焦于使用JUnit 5与Mockito这一经典组合,结合Sprin 阅读详情

相关推荐

Spring Boot进阶(53):「避免重复提交!Spring Boot 接口防重复请求的四种方式」

Spring Boot 如何防止重复请求?一文教你搞定它。

**My Coding Family** 3963

实现高并发秒杀的方式

java

blueheartstone的博客 1486

Win11显卡驱动安装失败的全面解决方案

Windows 11显卡驱动安装失败是一个比较常见的问题,但通过上述方法,我们可以有效地解决这一问题。方法一通过调整组策略编辑器的驱动程序安装策略,可能解决一些因签名问题导致的安装失败;而方法二则通过重装Windows 11系统,为系统提供一个全新的、干净的环境,从而可能解决更复杂的安装问题。在实际操作中,用户可以根据具体情况选择合适的方法来解决显卡驱动安装失败的问题。

nntxthml的博客 2662

springboot如何防止接口被多台服务器重复调用

Spring Boot 可以通过不同的方式来防止接口被多台服务器重复调用。下面介绍两种常用的方法: 使用分布式锁 可以使用分布式锁来控制接口的并发调用。当一个服务器正在处理接口请求时,其他服务器会被锁定,直到锁释放才能继续调用。常用的分布式锁实现有 Redis 分布式锁和 ZooKeeper 分布式锁等。 使用限流器 限流器可以控制接口的访问速率,防止被多台服务器同时调用。常用的限流器实现有 ...

weixin_42607969的博客 839

国产AI芯动力:复旦微FMQL100TAI900 FPGA原型验证板全解析

本文全面解析了复旦微FMQL100TAI900 FPGA原型验证板在国产AI硬件领域的创新突破。该板卡采用全栈国产化设计,具备出色的AI推理性能、视频处理能力和接口生态,特别适合工业质检、智能交通等场景。文章详细介绍了其芯片架构、存储子系统、接口扩展及电源设计,并分享了实战开发经验,为开发者提供了一套可靠的国产计算平台解决方案。

weixin_29250573的博客 457

完美解决LBP2900打印机安装驱动提示无法识别USB及连接错误等问题(附Win11全新安装支持及卸载方案)

LBP2900打印机虽然经典老旧,但在Win11上依然可以完美使用!许多网上教程都无视安装失败后的问题,在此分享一种全新、100%有效的方法来解决驱动连接错误和无法识别USB设备的问题。无论是新安装还是卸载重装,这个方法都适用。本文整合了通用驱动包,支持Win2000到Win11系统,操作简单,轻松摆脱安装困扰,享受无忧打印体验!

心开始の未来~的博客 2万+

springboot如何解决重复提交,接口短时间重复调用

springboot如何解决重复提交,接口短时间重复调用 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交…. 重复提交 字面意思就是提交了很多次,这种情况一般都是前端给你挖的坑…. 前段时间在开发中遇到一个这样的问题;前端小哥哥调用接口的时候存在 循环调用 的问题,正常情况下发送一个请求添加一条数据,结果变成了同一时刻并发的发送了 N 个请求,服务端瞬间懵.

nyasm的博客 1万+

【MDC开发者实战】多传感器融合算法在自动驾驶中的配置与优化

本文详细介绍了华为MDC平台在自动驾驶中多传感器融合算法的配置与优化实践。通过前融合与后融合技术,结合摄像头、激光雷达和毫米波雷达的数据,提升感知精度与可靠性。文章还分享了ARXML配置、标定技巧、算法调优及性能优化等实战经验,帮助开发者高效实现自动驾驶系统的传感器融合。

weixin_29214199的博客 515

springboot自定义注解实现防重复提交(服务缓存)

自定义注解实现防重复提交(服务缓存),单位时间内(unitTime)参数一样的重复请求会直接从redis中读取上次的缓存结果返回

bobjy_happybird的专栏 565

从零到一:如何用YOLOv8和PyQt5打造你的第一个花卉识别桌面应用

本文详细介绍了如何使用YOLOv8和PyQt5从零开始构建一个花卉识别桌面应用。涵盖环境搭建、数据准备、模型训练、界面设计、模型集成与性能优化等全流程,帮助开发者快速掌握深度学习目标识别技术的实际应用。

weixin_29048775的博客 454

Imatest-Dot Pattern

本文介绍了DotPattern模块测试方法,用于评估相机拍摄点阵图的表现。测试主要关注两点:色彩准确性(是否存在彩色噪点和杂边)和摩尔纹现象。测试步骤包括导入图片、选择分析区域、微调ROI、选择点状图类型和分析保存结果。测试结果包含横向色差、光学畸变和SMIATV畸变等数据,其中0.115%的色差值和0.004度的网格旋转角度表明相机表现良好,但-10.4%的SMIATV畸变显示存在明显桶形畸变。文章还提供了各项指标的具体解读标准。

weixin_64706696的博客 1352

Spring Boot 使用 AOP 防止重复提交

Java芋道源码2019-06-11 21:16:44 思路 Code 多线程测试 在传统的web项目中,防止重复提交,通常做法是:后端生成一个唯一的提交令牌(uuid),并存储在服务端。页面提交请求携带这个提交令牌,后端验证并在第一次验证后删除该令牌,保证提交请求的唯一性。 上述的思路其实没有问题的,但是需要前后端都稍加改动,如果在业务开发完在加这个的话,改动量未免有些大了,本节的...

u011277123的博客 3668

大数据领域数据产品的交通运输行业应用

您是否经历过早高峰被堵在桥上,看着导航显示“前方5公里缓行”却无能为力?是否见过货车司机绕远路导致成本飙升?这些“交通痛点”的背后,是传统交通管理依赖经验决策的局限。本文将聚焦“大数据数据产品”这一核心工具,从技术原理到实际应用,全面解析它如何为交通运输行业“开天眼”,解决从城市拥堵到物流效率的一系列难题。本文将按照“问题引入→概念拆解→技术原理→实战案例→应用场景→未来趋势”的逻辑展开,用生活化比喻降低理解门槛,用代码和数学模型提升专业性,最终帮您建立“大数据+交通”的完整认知框架。交通数据。

操作系统内核探秘的博客 237

MateCloud幂等控制:防止重复提交的3种实现方案

在分布式系统中,重复提交是一个常见的问题,可能导致数据不一致、业务逻辑错误等严重后果。MateCloud作为基于Spring Cloud Alibaba的微服务架构,提供了多种幂等控制方案,帮助开发者有效防止重复提交。本文将详细介绍MateCloud中实现幂等控制的3种方案,包括基于Token的前端控制、基于Redis的分布式锁以及基于数据库的唯一约束,帮助开发者根据实际业务场景选择合适的方案。

gitblog_00307的博客 658

【人工智能】AI 智能体驾驭工程(Harness Engineering)全解析

OpenAI将Harness定义为让Agent能完成有用工作的系统工程,Harness Engineering则是持续设计、实现、迭代这套系统的方法论;Anthropic将其概括为「让模型真正成为可靠Agent的基础设施」;Martin Fowler/Thoughtworks则将其定义为「控制Agent各层循环的规格、质量检查与工作流指导体系」。强大的AI模型是一匹爆发力极强的烈马;Prompt Engineering是「对马喊话的技巧」,Context Engineering是「给马看的地图」;

奶爸的编程之路,也就一周冷个三天 5245

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

非Controller控制层参数校验怎么办

本文介绍在非Controller控制层参数校验的两种方法

做一个有思想的技术人 2311

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

SpringBoot:基于 Redis 自定义注解实现后端接口防重复提交校验(幂等操作)

SpringBoot:基于 Redis 自定义注解实现后端接口防重复提交校验(幂等操作) 可基于 时间间隔 和 用于幂等判断的参数名称 实现防重复提交校验

初入江湖,多多关照 930

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

SeaTunnel Web 后端架构设计:Spring Boot + MyBatis 高性能实现

SeaTunnel Web 是 SeaTunnel 数据集成平台的可视化管理界面,基于 Spring Boot 和 MyBatis 构建高性能后端架构。本文将深入解析其核心架构设计、技术选型与实现细节,帮助开发者快速理解系统工作原理。 ## 核心技术栈选型 SeaTunnel Web 后端采用业界成熟的分层架构,主要技术组件包括: - **Spring Boot**:提供自动配置、依赖注入和

gitblog_00529的博客 577

spring boot,DAO层、ENTITY层、SERVICE层、CONTROLLER层之间的关系

5、View层 此层与Controller控制层结合比较紧密,需要二者结合起来协同工作。View层主要负责前台jsp页面的表示。另外一种总结1、DAO层: 持久层 主要与数据库进行交互DAO层主要是做数据持久层的工作,主要与数据库进行交互。DAO层首先会创建DAO接口,然后会在配置文件中定义该接口的实现类,接着就可以在模块中就可以调用DAO 的接口进行数据业务的而处理,并且不用关注此接口的具体实现类是哪一个类。DAO 层的数据源和数据库连接的参数数都是在配置文件中进行配置的。

clear10ve的博客 5267

springboot redis token_Spring Boot 使用 AOP 防止重复提交

作者:殷天文http://www.jianshu.com/p/09860b74658e在传统的web项目中,防止重复提交,通常做法是:后端生成一个唯一的提交令牌(uuid),并存储在服务端。页面提交请求携带这个提交令牌,后端验证并在第一次验证后删除该令牌,保证提交请求的唯一性。上述的思路其实没有问题的,但是需要前后端都稍加改动,如果在业务开发完在加这个的话,改动量未免有些大了,本节的实现方案无需前...

weixin_39522170的博客 413

Spring Boot Lock 本地锁 防止表单重复提交

参考 https://blog.youkuaiyun.com/weixin_30808575/article/details/95788091 import java.lang.annotation.*; //作用于方法 @Target(ElementType.METHOD) //整个运行阶段都可见 @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface LocalLock { String key() defaul

无术不学的博客 835

springboot aop使用_Spring Boot 使用 AOP 防止重复提交

作者:殷天文来源:www.jianshu.com/p/09860b74658e在传统的web项目中,防止重复提交,通常做法是:后端生成一个唯一的提交令牌(uuid),并存储在服务端。页面提交请求携带这个提交令牌,后端验证并在第一次验证后删除该令牌,保证提交请求的唯一性。上述的思路其实没有问题的,但是需要前后端都稍加改动,如果在业务开发完在加这个的话,改动量未免有些大了,本节的实现方案无需前端配合,...

weixin_39820244的博客 113

Spring Boot中Controller与Mapper层的CRUD注解详解:从入门到实战

Controller层职责保持“轻薄”,仅处理请求解析与响应封装,业务逻辑交给Service层。合理使用HTTP状态码(如201表示创建成功,204表示无内容)。Mapper层优化复杂SQL建议使用XML配置(如动态SQL<if><foreach>使用@Param明确参数名,避免因参数顺序导致的错误。注解选择简单CRUD推荐注解开发,复杂查询可结合MyBatis动态SQL标签。通过合理运用注解,开发者可以高效构建出结构清晰、易于维护的Spring Boot应用。欢迎交流指正!

ze15829163918的博客 2063

Spring Boot AOP 实战:优雅实现 Controller 全局日志统一打印

Spring Boot AOP 实战:优雅实现 Controller 全局日志统一打印

weixin_42326851的博客 2312

Spring Boot与Vue.js前后端分离项目实战:从零搭建健身管理平台

在现代Web开发中,前后端分离架构通过解耦用户界面与业务逻辑,已成为构建可维护、可扩展应用的主流范式。其核心原理在于后端专注于提供RESTful API接口处理数据和业务规则,前端则负责交互与展示,两者通过HTTP协议进行通信。这种模式的技术价值在于支持前后端并行开发、独立部署,并能更好地适应多端需求。在众多技术栈中,Spring Boot凭借其“约定大于配置”的理念和丰富的Starter依赖,能快速搭建稳健的后端服务;而Vue.js则以其响应式数据绑定和组件化开发,高效构建动态用户界面。将Spring B

weixin_30512089的博客 471

Spring Boot 项目为啥使用三层架构(Controller、Service、Repository)?

表现层/控制层(Controller):直接与用户或客户端交互,负责接收请求、解析参数并返回响应。好比餐厅中的服务员。业务逻辑层(Service):处理核心业务逻辑,包括数据校验、计算和流程控制。正如餐厅中负责烹饪的厨师。数据访问层(Repository / DAO):负责与数据库或其他数据源进行交互,执行数据的增删改查操作。相当于餐厅中负责备料和采购的人员。三层架构(Controller-Service-Repository)并非限制,而是 Spring Boot 项目高效运行的基石。职责分明,流程清晰。

2501_93078354的博客 1027
上一篇: 如何把本地项目上传到gitee上
下一篇: Failed to convert value of type ‘java.lang.String‘ to required type ‘java.time.LocalDate‘
tyjlearning
博客等级 码龄11年 24粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值