跟着JHipster学做项目 (5) 异常处理(上)Spring Boot后端

SpringBoot学习——全局处理异常 实际项目开发中,程序往往会发生各式各样的异常情况,特别是身为服务端开发人员的我们,总是不停的编写接口提供给前端调用,分工协作的情况下,避免不了异常的发生,如果直接将错误的信息直接暴露给用户,这样的体验可想而知,且对黑客而言,详细异常信息往往会提供非常大的帮助… 初窥异常 一个简单的异常请求的接口 @GetMapping("/test") public String test()... 阅读详情

JHipster处理异常的核心模块是zalando,zalando包含两种方式:

Spring boot

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>problem-spring-web-starter</artifactId>
    <version>${problem-spring-web.version}</version>
</dependency>

WebMVC

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>problem-spring-web</artifactId>
    <version>${problem-spring-web.version}</version>
</dependency>

spring boot方式容易在auto configuration上和其它模块引起冲突,JHipster采用了WebMVC方式。

首先,按照zalando要求,JHipster在JacksonConfiguration类中注册了两个模块,ProblemModule和ConstraintViolationProblemModule,通过注册这两个模块,可以使Response符合RFC 7807,例如:

 HTTP/1.1 403 Forbidden
   Content-Type: application/problem+json
   Content-Language: en

   {
    "type": "https://example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "balance": 30,
    "accounts": ["/account/12345",
                 "/account/67890"]
   }

通过注解@ControllerAdvice,以及对ProblemHandling, SecurityAdviceTrait的实现来完成对各类异常的捕捉,以及向前端返回ResponseEntity.

@ControllerAdvice
public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait {


    @ExceptionHandler
    public ResponseEntity<Problem> handleUsernameAlreadyUsedException(com.mycompany.myapp.service.UsernameAlreadyUsedException ex, NativeWebRequest request) {
        LoginAlreadyUsedException problem = new LoginAlreadyUsedException();
        return create(problem, request, HeaderUtil.createFailureAlert(applicationName,  true, problem.getEntityName(), problem.getErrorKey(), problem.getMessage()));
    }
}

此外在SecurityConfiguration中添加SecurityProblemSupport来处理安全异常捕捉

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private final TokenProvider tokenProvider;

    private final CorsFilter corsFilter;
    private final SecurityProblemSupport problemSupport;

    public SecurityConfiguration(TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
        this.tokenProvider = tokenProvider;
        this.corsFilter = corsFilter;
        this.problemSupport = problemSupport;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .antMatchers("/app/**/*.{js,html}")
            .antMatchers("/i18n/**")
            .antMatchers("/content/**")
            .antMatchers("/swagger-ui/index.html")
            .antMatchers("/test/**");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .csrf()
            .disable()
            .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
            .exceptionHandling()
                .authenticationEntryPoint(problemSupport)
                .accessDeniedHandler(problemSupport)
        .and()
            .headers()
            .contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:")
        .and()
            .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
        .and()
            .featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'")
        .and()
            .frameOptions()
            .deny()
        .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
            .authorizeRequests()
            .antMatchers("/api/authenticate").permitAll()
            .antMatchers("/api/register").permitAll()
            .antMatchers("/api/activate").permitAll()
            .antMatchers("/api/account/reset-password/init").permitAll()
            .antMatchers("/api/account/reset-password/finish").permitAll()
            .antMatchers("/api/**").authenticated()
            .antMatchers("/management/health").permitAll()
            .antMatchers("/management/info").permitAll()
            .antMatchers("/management/prometheus").permitAll()
            .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
        .and()
            .httpBasic()
        .and()
            .apply(securityConfigurerAdapter());
        // @formatter:on
    }


}

最后,近距离观察一下JHipster所定义的exception, 以UsernameAlreadyUsedException为例,JHipster分别在service和web.rest层两次定义这个异常,避免了service层无法调用web.rest层类的需要。

Service层异常定义:

package com.mycompany.myapp.service;

public class UsernameAlreadyUsedException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public UsernameAlreadyUsedException() {
        super("Login name already used!");
    }

}

web.rest层异常定义:

package com.mycompany.myapp.web.rest.errors;

public class LoginAlreadyUsedException extends BadRequestAlertException {

    private static final long serialVersionUID = 1L;

    public LoginAlreadyUsedException() {
        super(ErrorConstants.LOGIN_ALREADY_USED_TYPE, "Login name already used!", "userManagement", "userexists");
    }
}

JHipster对异常信息国际化交给了前端处理,下一篇文章会提到。

Good Luck,

Cheers!

 

全局异常统一处理方案(zalando) 使用第三方jar包zalando处理全局异常 阅读详情

相关推荐

Security框架:通过CorsFilter解决前端跨域请求问题

项目情况:  最近做的pmdb项目是前后端分离的, 由于测试的时候是前端与后端联调,所以出现了跨域请求的问题。浏览器默认会向后端发送一个Options方式的请求,根据后端的响应来判断后端支持哪些请求方式,支持才会真正的发送请求。 CORS介绍: CORS(Cross-Origin Resource Sharing 跨源资源共享),当一个请求url的协议、域名、端口三者之间任意一与当前页...

我滴太阳233的博客 7240

开源项目【Problem-Spring-Web】指南及常见问题解决方案

**Problem-Spring-Web** 是一个专为 Spring Web MVC 和 Spring WebFlux 设计的库,旨在简化应用中生成符合 `application/problem+json` 格式的响应过程。此项目由 Zalando 提供,它巧妙地将 [Problem](https://tools.ietf.org/html/rfc7807) 库融入到 Spring 的异常处理机...

gitblog_01022的博客 450

problem-spring-web:用于处理Spring Web MVC中的问题的库

Spring MVC和Spring WebFlux的问题 问题Spring Web是一组库,可轻松从Spring应用程序生成响应。 它填补了一个小众市场,它连接了和或从而使它们可以无缝地协同工作,而只需最少的开发人员工作。 在此过程中,它旨在一次完成一个小而重复的任务。 该库的工作方式基于我们所谓的建议特征。 通知特征是一个小的,可重用的@ExceptionHandler实现为放在单个方法接口中的。 这些建议特征可以自由组合,并且不需要为使用公共基类。 :magnifying_glass_tilted_right: 请查看获得详细介绍! 产品特点 让您选择点菜特色 偏重于继承而不是继承 内置约20个有用的建议特征 Spring MVC和Spri

推荐开源项目:Zalando's `problem-spring-web` - 精细化错误处理的Spring Web增强库

是一个基于Spring Web框架的扩展库,旨在帮助开发者优雅地处理HTTP状态码和异常信息。该项目提供了易于使用的注解和类,使得在你的Spring应用中集成RESTful API的错误响应变得更加规范且直观。 ## 技术分析 ### 1. 易于集成 `problem-spring-web` 完全兼容Spring MVC,只需要添加依赖即可轻松集成到现有的Spring应用中。它利用了Spri...

gitblog_00009的博客 509

problem-spring-web, 在 spring Web MVC中,处理问题的库.zip

problem-spring-web, 在 spring Web MVC中,处理问题的库 Web站点MVC问题 问题 spring 是一个库,它使得从 spring 应用程序中生成 application/problem json 响应变得容易。 工具填补了一个利基,它将问题库和mvc处理网络异常连接在

ARM Cortex-M系列授权解析:从研发到量产的免费与付费之路

本文深入解析了ARM Cortex-M系列内核从研发到量产过程中的授权模式。研发阶段可利用ARM DesignStart等免费资源进行原型验证,但产品商业化量产则需支付授权费与版税。文章对比了采购商用MCU与自研芯片的成本差异,并探讨了RISC-V作为免费替代方案在IoT领域的应用前景与挑战,为开发者提供了清晰的选型指南。

weixin_29292431的博客 494

跟着JHipster学做项目 (6) 安全访问控制(上)JWT的Spring Boot应用

通过配置可以生成JHipster运用JWT进行访问控制的一套代码,主要是通过JWTFilter过滤器,并把它置于UsernamePasswordAuthenticationFilter前端对用户进行Authentication(认证)和Authorization(授权)控制,此外对于认证或者授权失败是采用前文提到的异常处理。 这里需要引入的依赖如下: <dependency> <groupId>org.springframework.boot</groupId&g

java_augur的专栏 1480

Unity海康视屏对接

通过对接海康SDK,获取视屏流回调。经过解码得到YUV格式的图片,最后通过Shader把YUV数据显示出来。也可以通过Rtsp协议,直接获取视屏流显示。这个貌似Unity中已经有插件支持了,UMP。------2018.4.20using UnityEngine;using System.Collections;using System;using UnityEngine.UI;using Sys...

Witness_K的博客 2028

ESP-IDF GPTimer 通用硬件定时器完整指南:5 态状态机、3 种警报模式与 5 个调优开关深度拆解

ESP-IDF 中的 GPTimer 驱动(`esp_driver_gptimer` 组件)封装了 ESP32 系列芯片的通用硬件定时器外设,提供纳秒级分辨率计数、硬件警报与自动重载能力。本文从驱动内部状态机讲起,逐字段拆解 `gptimer_config_t` 与 `gptimer_alarm_config_t` 的语义,给出一次性警报、周期警报、软件定时器链表三种实战模式的可运行代码,最后覆盖

gitblog_00241的博客 928

c++通过自然语言处理技术分析语音信号音高

其中,缓冲区大小为2048,最小基频为80Hz,最大基频为1000Hz。通常情况下,音高在85Hz到255Hz之间,因此可以根据实际情况修改最小和最大基频值。C++中可以使用数字信号处理库或语音处理库,比如MATLAB、Praat、YIN算法等等来进行音高分析。对于语音信号的音高分析,可以使用基频提取技术。基频是指一个声音周期的重复率,也就是一个声音波形中最长的周期。通常情况下,人的声音基频范围是85Hz到255Hz。这段代码使用了YIN算法来计算语音信号的基频,得出的结果即为音高。

SYC20110120的博客 1727

SFF-8654接口引脚定义全解析:从SAS到U.2的高速硬件连接核心

在高速数据存储与传输领域,接口标准是连接主机与存储设备、确保信号完整性与协议互通性的物理基础。其核心原理在于通过精确定义的物理引脚和电气特性,承载不同的高速串行通信协议,如SAS和PCIe。这类高密度连接器的技术价值在于以紧凑的形态支持多协议兼容与高速率传输,满足了企业级存储、高性能计算对带宽和可靠性的苛刻要求。典型的应用场景包括服务器硬盘背板连接、NVMe U.2固态硬盘直连以及外部存储扩展。本文聚焦于SFF-8654(亦称Mini SAS HD)这一关键接口,深入剖析其引脚定义、信号分区(如高速数据通道

weixin_29188043的博客 706

SpringBoot中jackson自定义序列化

SpringBoot中jackson自定义序列化以及空值序列化处理

眼前一座山,踏平它 2555

要理解成本中心与利润中心的根本区别与适用场景,需从 “责任范围、考核核心、管理目标” 三个核心维度切入,同时明确二者在企业管理体系中的联动关系

摘要: 成本中心与利润核心区别在于责任范围、考核目标和管理权限。成本中心仅对成本负责(如生产、行政部门),考核成本控制能力;利润中心需同时管控成本与收入(如独立产品线、区域分公司),以利润为核心指标。选择标准取决于单元是否拥有收入决策权:无收入权的支持/执行部门设为成本中心,能独立经营、核算盈亏的单元设为利润中心。二者协同运作,成本中心为利润中心提供基础支持,利润中心的需求动态影响成本中心资源配置,共同实现企业整体目标。划分本质是确保考核指标与责任范围匹配,避免管理失效。

金牌架构师 656

JHipster关闭Liquibase

spring: profiles: active: dev include: - swagger - no-liquibase

bingzhilingyi的博客 790

Apifox接口测试+自动化测试

Apifox 接口测试+自动化测试快速入门!

程序员小杨哥的博客 1万+

前言:为什么要学习爬虫和逆向,该如何学习?

学习爬虫和逆向技术是当今数字化时代的重要技能,尤其在数据分析、安全研究、自动化工具开发等领域有广泛应用。以下是详细的学习理由、路径和方法:

数据知道的博客 1万+

Problem Spring Web 使用教程

`Problem Spring Web` 是一个用于在 Spring Web MVC 应用中处理问题的库。它遵循 RFC 7807 规范,使得应用能够轻松地生成 `application/problem+json` 响应。该库通过提供一系列的 `advice traits`,简化了异常处理的流程,使得开发者能够更专注于业务逻辑而非异常处理细节。 ## 项目快速启动 ### 依赖引入 首先,在...

gitblog_00020的博客 1031

开源工具对比:5款主流大数据脱敏框架评测

数据脱敏(Data Masking/Anonymization),也称为数据漂白、数据去标识化,是指在不影响数据可用性的前提下,通过一定的技术手段对敏感信息进行处理,使其无法被识别或关联到具体个人或实体的过程。当应用程序向数据库写入数据(INSERT/UPDATE)时,ShardingSphere 会拦截 SQL,对配置了脱敏规则的字段,使用指定的算法进行加密/脱敏处理,然后将处理后的数据写入到。如果你的答案是“是”,那么数据脱敏,尤其是针对海量数据的。好的,各位技术同仁,数据安全领域的探索者们,大家好。

小程序开发 1183

第三方异常处理(org.zalando)0.27.0版本,关闭stackTrace显示。

第三方异常处理(org.zalando)0.27.0版本,关闭stackTrace显示 没有配置WebConfiguration前,通过IDEA的HTTP Client工具模拟请求,数据响应 Content length: 15773 bytes 配置WebConfiguration​​​​​​​后,数据响应 Content length: 138 bytes 前后的响应大小非常可观,并且清爽了不少。...

智慧,不是知识、不是经验、不是思辩,而是超越自我中心的态度。 947

深度学习工具包 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")

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

jhipster自定义异常处理

ExceptionTranslator  是jhipster自己提供异常处理机制,其中org.zalando.problem.Problem#getDetail可以拿到异常发生的信息,getStatus来获取状态码,定制自己异常返回格式,就可以了...

m0_38105216的博客 921

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Zalando Problem 开源项目教程

Zalando Problem 是一个用于处理 HTTP 问题的 Java 库,它提供了一种标准化的方式来表示和处理 RESTful API 中的错误。这个库的主要目的是简化错误处理流程,使得开发者能够更容易地定义和返回一致的错误响应。 Zalando Problem 遵循 RFC 7807 规范,该规范定义了一种在 HTTP 响应中传输问题详细信息的通用格式。通过使用 Zalando Prob...

gitblog_00567的博客 803

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

SpringBoot依赖管理特性

官方所有的 starter 在官网:https://docs.spring.io/spring-boot/docs/2.3.4.RELEASE/reference/html/using-spring-boot.html#using-boot-starter 下找到。这里面已经声明了我们开发中可能会遇到的所有的依赖版本信息;所有场景启动器最底层的依赖是 spring-boot-starter 依赖,该依赖在 spring-boot-starter-web-2.3.4.RELEASE.pom 中。

少年闰土 4102

Spring-WebFlux简介与使用

简介Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架。 与Spring MVC不同,它不需要Servlet API,完全异步和非阻塞, 并通过Reactor项目实现Reactive Streams规范。 并且可以在诸如Netty,Undertow和Servlet 3.1+容器的服务器上运行。Reactor中的Mono和FluxFlux 和 Mono...

白开水_Arvin的博客 2万+

JHipster 中的设计(1)RESTful API Response 与异常处理的设计

一、 Response 设计 在JHipster生成的项目中,RESTful API的Response相比一些传统的方式,特别的依赖了Response.header来传输一些附加信息,比如分页请求结果中的总数、执行的方法代码等。下面以用户相关接口为例: name method uri body Get User GET /users/{userId} ...

程序员进阶之路 4529

SpringBoot框架实现跨域访问学习

引言: 最近有时间,就找了点资料,把工作中用到的SpringBoot配置跨域CORS访问仔细研究一下: 在Java 编程中,web项目还是经常遇到一些跨域的使用。这里主要记录几种spring框架,spring boot中的一些常见的几种配置跨域的方法。 CORS(Cross-origin resource sharing-跨源资源共享)允许网页从其他域向浏览器请求额外的资源,例如 字体...

coding_1994的博客 861
上一篇: 跟着JHipster学做项目 (4)审计功能
下一篇: 跟着JHipster学做项目 (5) 异常处理(下)Vue前端
java_augur
博客等级 码龄22年 67粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值