具有中央异常处理和VO验证的Spring Data JPA –框架

1.简介

一段时间以来,Spring框架已成为事实上的标准,可以创建任何基于REST API的应用程序。 Spring提供了各种现成的组件,以避免编写重复而繁琐的样板代码。 另外,关于Spring的美丽之处在于,如果有现成的解决方案,它就可以解决。 它为您提供了与现有库/框架集成的简便方法。 在本文中,让我们看看如何使用全栈Spring技术编写基于Spring的RESTful API。 Spring Boot,Spring Validations和Spring数据JPA的示例显示了以下方面的完整信息:

  • Spring Boot及其配置
  • 使用Spring Boot Starters进行依赖管理
  • 使用Spring数据JPA避免瓶颈DAO代码。
  • Spring支持VO级别的验证。
  • 集中式异常处理。

我们使用Gradle进行依赖管理并作为构建工具。 让我们逐步进行。

2.生成项目

这是生成项目所需遵循的步骤。

2.1 Spring Intializer

Spring在此位置Spring INITIALIZR提供了易于启动的项目生成工具。 在此网页上,您可以通过添加所需的依赖项来引导应用程序。 您可以通过添加下面提到的3个依赖项来生成项目框架(请参见下图以清楚了解)。
1.'Web':此依赖关系是编码Web层和创建API所必需的。 生成项目后,它在build.gralde文件中显示为以下依赖项。
compile('org.springframework.boot:spring-boot-starter-web') 2.'Validation':启用弹簧验证。 它在build.gradle中显示为以下依赖项。 compile('org.springframework.boot:spring-boot-starter-validation') 3.'JPA':启用弹簧数据JPA。 它在build.gradle中显示为以下依赖项。 compile('org.springframework.boot:spring-boot-starter-data-jpa')

Spring Data JPA-Spring初始化器

弹簧初始化器

2.2 Eclipse配置

生成项目并将其导入到Eclipse中。 完成此操作后,就可以创建API。 在eclipse中导入的项目应如下所示。

Spring Data JPA-项目结构

项目结构

3.创建API

在编写API之前,让我们根据Java约定创建包,如下所示。

Spring Data JPA-Java软件包

Java包

使用生成的代码,我们在根包中获得一个类,即com.example.spring.springrestapp。 这是我们的启动类。

Spring Data JPA-启动类

入门班

注意:应该使用默认配置在根软件包级别创建启动类。
现在,让我们继续创建控制器类和API方法,以向数据库添加用户详细信息。 对于我们将要构建的该API,让我们假设一些约束作为我们的要求:

  • 该API应该收集用户的名字,姓氏,电子邮件,地址和电话号码并将其存储在MySQL DB中
  • API调用者将姓,名和电子邮件作为必填字段传递。 电子邮件应经过格式验证。
  • 家庭住址和电话号码可以是可选的。

4.配置数据库详细信息:

对于此项目,您需要运行MySQL DB的本地实例。 您可以在application.properties中提供数据库详细信息,如下所示。

应用特性

spring.datasource.url = jdbc:mysql://localhost:3306/boot_app
spring.datasource.username = root
spring.datasource.password = root

在MySQL DB中,使用以下脚本在MySQL DB中创建一个包含名字,姓氏,电子邮件,地址和电话号码的表。

创建表脚本

create table user_info(
user_id smallint(10) primary key auto_increment,
first_name varchar(150),
last_name varchar(150),
email varchar(200),
address varchar(250),
phone smallint(10)
);

5.配置Spring Data JPA

表准备好后,我们需要使用JPA将其映射为Java对象。 该表的每个字段都使用注释映射到java对象中。 以下是我们实体的外观。

JPA实体

package com.example.spring.springrestapp.dao.entity;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;import org.springframework.data.annotation.Id;@Entity
@Table(name = "user_info")
public class UserInformation {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "USER_ID")private Integer userId;@Column(name = "FIRST_NAME")private String firstName;@Column(name = "LAST_NAME")private String lastName;@Column(name = "EMAIL")private String email;@Column(name = "ADDRESS")private String address;@Column(name = "PHONE")private Integer phone;public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Integer getPhone() {return phone;}public void setPhone(Integer phone) {this.phone = phone;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}
}

现在,创建Spring数据JPA存储库。 可以通过如下扩展接口JpaRepository来创建数据JPA存储库。 (请注意,您需要传递ID字段的实体和数据类型。在我的示例中,entity是User,而id字段的类型是Integer)

JPA存放区

package com.example.spring.springrestapp.dao.repo;import org.springframework.data.jpa.repository.JpaRepository;
import com.example.spring.springrestapp.dao.entity.UserInformation;
public interface UserRepo extends JpaRepository {}

如此简单,我们的DAO代码已准备就绪! Spring负责生成基础的DAO实现。

6.服务和控制器层

现在,我们创建一个服务类来保存用户详细信息。 您可以根据需要在方法中添加业务逻辑。

服务等级

@Service
public class UserDetailService {@Autowiredprivate UserRepo userRepo;public UserInformation saveUser(UserInformation user) {return userRepo.save(user);}
}

现在让我们创建一个控制器和API方法。 saveUser api在请求正文中接受json数据,然后在正文中以JSON形式返回响应。

控制器层

@RestController
@RequestMapping("/api/user")
public class SpringRestAppController {@Autowiredprivate UserDetailService userService;@PostMapping(value = "/save")public @ResponseBody UserInformation createUser(@RequestBody UserInformation user) {return userService.saveUser(user);}
}

@RequestMapping用于映射资源。
@PostMapping与分配给@RequestMapping HttpPost相同。

7.配置VO级别验证

我们的API需要按照开头提到的要求对其收到的数据进行验证。 为此,我们将在实体级别应用数据验证,如下所示。

数据验证

@Entity
@Table(name = "user_info")
public class UserInformation {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "USER_ID")private Integer userId;@Column(name = "FIRST_NAME")@NotBlank(message = "first name can't be blank")private String firstName;@Column(name = "LAST_NAME")@NotBlank(message = "last name can't be blank")private String lastName;@Column(name = "EMAIL")@NotBlank(message = "email can't be blank")@Email(message = "invalid format")private String email;@Column(name = "ADDRESS")private String address;@Column(name = "PHONE")private Integer phone;

请注意,注释@NotBlank不允许为空或null值, @Email不能检查有效的电子邮件格式。 此外,我们添加了验证失败的消息。

现在,我们需要告诉Spring按照实体中指定的注释进行验证。 为此,我们可以在请求有效负载上使用@Valid注释,如下所示。

@PostMapping(value = "/save")public @ResponseBody User createUser(@RequestBody @Valid UserInformation user) {return userService.saveUser(user);}

8.配置异常处理

验证失败时,我们需要将正确格式的错误响应提供给API使用方。 例如,如果没有给出名字,我想以以下格式返回错误消息,并带有HTTP错误代码错误请求。 为API使用者提供异常堆栈跟踪不是一个好主意。

{
"errorCode": "VALIDATION_FAILED",
"message": ""
}

我们可以在每个API控制器方法中执行此操作,也可以创建单个全局异常处理,从而避免出于相同需求在多个位置编写重复代码。
为了在一个地方处理中央异常,我们利用了Spring的错误处理程序。 在Spring 3.2中,提供了@ControllerAdvice以全球化异常/错误处理。 要返回错误响应,请创建一个具有错误代码和消息的VO。

值对象中的错误处理

@JsonInclude(content = Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ApiErrorVO {private String errorCode;private String message;public ApiErrorVO(String errorCode, String message) {super();this.errorCode = errorCode;this.message = message;}

当验证失败时,Spring会抛出MethodArgumentNotValidException 。 我们可以捕获此异常并从抛出的异常中提取错误消息。 我们使用@ExceptionHandler捕获异常,如下所示。

异常处理

@ControllerAdvice
public class ApiExceptionHandler {@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(code = HttpStatus.BAD_REQUEST)@ResponseBodypublic ApiErrorVO handleValidationError(MethodArgumentNotValidException ex) {BindingResult bindingResult = ex.getBindingResult();FieldError fieldError = bindingResult.getFieldError();String defaultMessage = fieldError.getDefaultMessage();return new ApiErrorVO("VALIDATION_FAILED", defaultMessage);}
}

@ResponseStatus用于指定HTTP错误的请求状态。
@ResponseBody确保将错误写入响应正文。

9.结论

现在让我们测试一下API。

情况1:验证失败
网址: http://localhost:8080/restApp/api/user/save
RequestPayload:请注意空白的名字

{
"firstName":"",
"lastName":"K",
"email":"alexk@abc.com"
}

响应:HTTP状态为400

{
"errorCode": "VALIDATION_FAILED",
"message": "first name can't be blank"
}

情况2:提供所有必需值时
请求有效负载:

{
"firstName":"Alex",
"lastName":"K",
"email":"alexk@abc.com"
}

响应:HTTP状态为200

{
"userId": 8,
"firstName": "Alex",
"lastName": "K",
"email": "alexk@abc.com",
"address": null,
"phoneNumber": null
}

测试结束。

10.下载源代码

下载
您可以在此处下载完整的源代码: SPRING DATA JPA

翻译自: https://www.javacodegeeks.com/2018/08/spring-data-jpa-central-exception-handling-vo-validations-framework.html

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

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

相关文章

初识斯蒂尔杰斯积分(Stieltjes integral)

https://blog.csdn.net/Northernland/article/details/83051415

drools6.5_使用Drools 6.0进行部署

drools6.5KieScanner 6.0 KieScanner取代了5.x KnowledgeAgent。 它使用嵌入式Maven允许在运行时解析和检索jar。 6.0应用程序现在可以轻松支持依赖关系和可传递依赖关系; 使用众所周知的Maven语义进行版本控制。 它允许在类路径上部署,也可以在运行时动…

双子(Dioid)

双子代数是若其对任意无限多元的 “和”封闭且乘法对此无限和具分配律。 https://baike.baidu.com/item/%E5%8F%8C%E5%AD%90%E4%BB%A3%E6%95%B0

具有外部Zookeeper集成并使用SOLRJ API访问数据的SOLR cloud 7.4集群配置

SOLR是最流行且高度可扩展的搜索引擎之一,它基于分布式索引技术运行。 Solr索引几乎可以基于任何类型的数据源(CSV数据或XML数据或从RDBMS数据库或标准文件系统中提取的数据)构建。 对于以RDBMS数据库作为后端构建的任何Web应用程序&#xf…

随机过程及其稳态stability

1. 为什么要研究随机过程? 人类认识世界的历史,就是一认识和描绘各种运动的历史,从宏观的天体运动到分子的运动,到人心理的运动-我们通称为变化,就是一个东西随时间的改变。 人们最成功的描绘运动的模型是牛顿的天体…

求离散马尔科夫链的平稳分布+按照一定概率分布生成想要的样本

1. 求离散马尔科夫链的平稳分布的两种解法 假设离散马尔科夫链的转移矩阵为P PP,平稳分布为π \piπ,则平稳分布满足: PππP \pi \piPππ 1.1 迭代法 求平稳分布的一种简单方法是迭代法,即随机初始化初始分布π 0 \pi_0π 0 …

MCMC 和 Gibbs采样

0. MCMC 从名字我们可以看出,MCMC由两个MC组成,即蒙特卡罗方法(Monte Carlo Simulation,简称MC)和马尔科夫链(Markov Chain ,也简称MC)。 Monte Carlo (蒙特卡罗&#x…

使用Java流和In-JVM-Memory的超低延迟查询

自然界的基本规则(例如光速和通用信息论)对我们可以从传统系统体系结构中获得的最大性能设置了明显的限制。 了解您作为Java开发人员如何使用JVM技术和Java流将性能提高几个数量级。 例如,如果应用程序服务器和数据库服务器相距100 m&#…

信道接入技术及协议

1. 信道共享方式 在普通的通信系统中,信道共享方式有3种:点对点、点对多点和多点共享。 1.1 点对点 点对点是最简单的信道共享方式。其特点是只有两个节点共享无线信道。在单信道时,两个节点可以通过半双工方式实现共享,在双信…

MATLAB | 解决打开延迟的情况

问题 最近打开matlab,一直没有反应,大概几分钟后,才开始有反应。 网上关于matlab启动出现延迟的方法有很多种解决方法。但都是针对破解版的,而装正版matlab2020b,缺少license文件。对于此,我们尝试用另外一…

50 个具有挑战性的概率问题 [01/50]:袜子抽屉

一、说明 我最近对与概率有关的问题产生了兴趣。我偶然读到了弗雷德里克莫斯特勒(Frederick Mosteller)的《概率论中的五十个具有挑战性的问题与解决方案》(Fifty Challenge Problems in Probability with Solutions)一书。我认为…

制作程序化装饰花纹图案_装饰图案

制作程序化装饰花纹图案装饰图案 我不经常使用的一种设计模式是Decorator 。 我不确定为什么这种模式不受欢迎,因为它很方便。 装饰器模式允许以受控方式向对象添加功能。 即使在使用静态类型的语言时,也可以在运行时运行! 装饰器模式是子类的…

6个您需要了解的日志管理工具(以及如何使用它们)

如果没有正确的工具来汇总和解析日志数据,则几乎不可能找到并了解您正在寻找的信息。 日志有无穷无尽的用途,因为日志本身是无止境的。 应用程序日志,安全日志,BI日志, 林肯日志 (好吧,也许不是…

JDK 12开关表达式遇到意外的枚举值

正如我在“ 玩JDK 12的Switch表达式 ”一文中所写的那样, JDK 12 Early Access Build使JEP 325的实现(“ Switch Expressions(Preview)”)的实验变得容易。 我的帖子“ JDK 12:实际中的切换语句/表达式 ”使…

Matlab画图线型、符号及颜色设置

1. matlab 中线条的主要属性 Color: 颜色LineStyle: 线型LineWidth: 线宽Marker: 标记点的形状MarkerFaceColor: 标记点填充颜色MarkerEdgeColor: 标记点边缘颜色MarkerSize: 标记点大小 2. 各种属性的名称 2.1 线型 -Solid line (default) – Dashed line : Dotted line …

休眠面试问答-最终清单

这是有关Hibernate Framework的一些最重要问题的摘要,可能会要求您在访谈中回答! 您无需担心下一次面试的机会,因为Java Code Geeks在这里为您服务! 您可能会被问到的大多数事情都收集在下面的列表中。 我们的Hibernate面试问题将…

matlab 进度条/waitbar 显示运行进度

当运行大程序,需要跑大量数据的时候,使用进度条可以看到程序究竟运行到什么地方了,哈哈,要不干等着难受(╯﹏╰)…… waitbar的作用是打开或者更新进度条。 1 语法结构 (1.1) h waitbar(x,‘message’) x表示进度条的比例长度…

MATLAB 命令 BOXPLOT

Matlab中有关boxplot(X)命令的解释: boxplot(X) produces a box and whisker plot for each column of the matrix X. The box has lines at the lower quartile, median, and upper quartile values. Whiskers extend from each end of the box to the adjacent v…

latex-bib参考文献人名特殊字符

https://blog.csdn.net/weixin_43413198/article/details/105468843

Matlab RGB 颜色对照表(0-1之间取值)

https://blog.csdn.net/qq_38882446/article/details/100886087