Spring REST:异常处理卷。 3

这是该系列中有关Spring REST异常处理的最后一篇文章。 最后,这次我将讨论在表单处理期间可能发生的REST异常的处理。 因此,在本教程中,您将看到与REST,表单和异常处理有关的所有内容。 客户端呢? jQuery将用于反映REST服务的所有响应。

与以前的教程一样,我将使用Smartphone应用程序 。 现在是宣布此帖子主要目的的好时机– 智能手机实体需要在创建和编辑之前进行验证。

让我们看一下更新的Smartphone类:

@Entity
@Table(name="smartphones")
public class Smartphone {@Id@GeneratedValueprivate Integer id;@Length(min=1, max=20)private String producer;@Length(min=1, max=20)private String model;@Range(min=1, max=1500)private double price;/*** Method updates already existed {@link Smartphone} object with values from the inputed argument.* @param sPhone - Object which contains new Smartphone values.* @return {@link Smartphone} object to which this method applied.*/public Smartphone update(Smartphone sPhone) {this.producer = sPhone.producer;this.model = sPhone.model;this.price = sPhone.price;return this;}@Overridepublic String toString() {return producer+": "+model+" with price "+price;}//getters and setters are omitted}

请注意@Length@Range批注。 这些注释是bean验证的标准方法。 在通过添加以下依赖项来更新已存在的pom.xml文件之后,可以使用这些注释:

org.hibernatehibernate-validator5.0.1.Finaljavax.validationvalidation-api1.1.0.Final

在此之后,我需要更新messages.properties文件:

Length.smartphone.producer = Length of a Smartphone producer should be from 1 to 20 characters.
Length.smartphone.model = Length of a Smartphone model should be from 1 to 20 characters.
Range.smartphone.price = Price of a Smartphone should be from 1 to 1 500.00 $

现在,让我们看一下SmartphoneController类中的createSmartphone方法:

...@RequestMapping(value="/create", method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE,consumes = MediaType.APPLICATION_JSON_VALUE)@ResponseBodypublic Smartphone createSmartphone(@RequestBody @Valid Smartphone smartphone) {return smartphoneService.create(smartphone);}
...

@Valid注释应用于方法参数。 要特别注意缺少BindingResult ,它不需要像传统的Spring MVC应用程序中那样进行验证。 如果Smartphone对象中的某些属性的值不合适,则@Value批注将引发MethodArgumentNotValidException

在实体创建/编辑期间处理异常需要使用不同的模型来表示信息。 我的意思是上一篇文章中的 ErrorInfo类。 我们需要传输其他信息,其中包含错误字段名称和该字段的某些错误消息。 为此,这里是一个新类:

public class ErrorFormInfo {private String url;private String message;private List< FieldErrorDTO > fieldErrors = new ArrayList< FieldErrorDTO >();public ErrorFormInfo() {}public ErrorFormInfo(String url, String message) {this.url = url;this.message = message;}public ErrorFormInfo(List< FieldErrorDTO > fieldErrors, String url, String message) {this.fieldErrors = fieldErrors;this.url = url;this.message = message;}//getters and setters are omitted}

第二个类是FieldErrorDTO它在上面的代码示例中使用:

public class FieldErrorDTO {private String fieldName;private String fieldError;public FieldErrorDTO(String fieldName, String fieldError) {this.fieldName = fieldName;this.fieldError = fieldError;}//getters and setters are omitted}

引入错误传输对象后,我可以继续@ControllerAdvice类中的错误处理。 这是RestExceptionProcessor类的代码片段:

...@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(value=HttpStatus.BAD_REQUEST)@ResponseBodypublic ErrorFormInfo handleMethodArgumentNotValid(HttpServletRequest req, MethodArgumentNotValidException ex) {String errorMessage = localizeErrorMessage("error.bad.arguments");String errorURL = req.getRequestURL().toString();ErrorFormInfo errorInfo = new ErrorFormInfo(errorURL, errorMessage);BindingResult result = ex.getBindingResult();                List< FieldError > fieldErrors = result.getFieldErrors();errorInfo.getFieldErrors().addAll(populateFieldErrors(fieldErrors));return errorInfo;}/*** Method populates {@link List} of {@link FieldErrorDTO} objects. Each list item contains* localized error message and name of a form field which caused the exception.* Use the {@link #localizeErrorMessage(String) localizeErrorMessage} method.* * @param fieldErrorList - {@link List} of {@link FieldError} items* @return {@link List} of {@link FieldErrorDTO} items*/public List< FieldErrorDTO > populateFieldErrors(List< FieldError > fieldErrorList) {List< FieldErrorDTO > fieldErrors = new ArrayList< FieldErrorDTO >();StringBuilder errorMessage = new StringBuilder("");for (FieldError fieldError : fieldErrorList) {errorMessage.append(fieldError.getCode()).append(".");errorMessage.append(fieldError.getObjectName()).append(".");errorMessage.append(fieldError.getField());String localizedErrorMsg = localizeErrorMessage(errorMessage.toString());fieldErrors.add(new FieldErrorDTO(fieldError.getField(), localizedErrorMsg));errorMessage.delete(0, errorMessage.capacity());}return fieldErrors;}/*** Method retrieves appropriate localized error message from the {@link MessageSource}.* * @param errorCode - key of the error message* @return {@link String} localized error message */public String localizeErrorMessage(String errorCode) {Locale locale = LocaleContextHolder.getLocale();String errorMessage = messageSource.getMessage(errorCode, null, locale);return errorMessage;}
...

可以通过本文开头的链接找到RestExceptionProcessor类的完整版本。 我希望上面的代码片段能自我解释。 如果否,请随时在评论中提问。

我需要做的最后一件事是开发客户端代码端:

$(document).ready(function() {$('#newSmartphoneForm').submit(function(event) {var producer = $('#producer').val();var model = $('#model').val();var price = $('#price').val();var json = { "producer" : producer, "model" : model, "price": price};$.ajax({url: $("#newSmartphoneForm").attr( "action"),data: JSON.stringify(json),type: "POST",beforeSend: function(xhr) {xhr.setRequestHeader("Accept", "application/json");xhr.setRequestHeader("Content-Type", "application/json");$(".error").remove();},success: function(smartphone) {var respContent = "";respContent += "Smartphone was created: [";respContent += smartphone.producer + " : ";respContent += smartphone.model + " : " ;respContent += smartphone.price + "]";$("#sPhoneFromResponse").html(respContent);                   },error: function(jqXHR, textStatus, errorThrown) {var respBody = $.parseJSON(jqXHR.responseText);var respContent = "";respContent += "";respContent += respBody.message;respContent += "";$("#sPhoneFromResponse").html(respContent);$.each(respBody.fieldErrors, function(index, errEntity) {var tdEl = $("."+errEntity.fieldName+"-info");tdEl.html(""+errEntity.fieldError+"");});}});event.preventDefault();});});

客户端new-phone.jsp文件的完整版本可通过本文开头的链接找到。

到此为止,我必须对上面文章中开发的所有内容进行演示。 因此场景很简单,我将打开“新智能手机”页面并提交包含无效数据的表单。

sr1

摘要

我希望我关于Spring REST应用程序中异常处理的三篇文章对您有所帮助,并且您学到了一些新知识。 这些文章仅重点介绍了异常处理的基本流程,以及您只能在实际项目的整个实践中获得的所有其他内容。 感谢您阅读我的博客。

参考: Spring REST:异常处理卷。 Fruzenshtein的笔记博客中来自JCG合作伙伴 Alexey Zvolinskiy的3 。

翻译自: https://www.javacodegeeks.com/2013/12/spring-rest-exception-handling-vol-3.html

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

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

相关文章

centos6安装mysql并远程连接_Ubantu下MySQL安装、部署和远程连接

系统阿里云 ubantu 16.04MySQL 5.0/8.0连接工具 Navicat Premium安装MySQL1、MySQL 5.0直接使用apt命令安装sudo apt install mysql-server输入密码完成安装。安装完mysql-server后&#xff0c;mysql-client就带了&#xff0c;无需单独安装安装成功后输入如下命令检查数据库状态…

linux强制用户改密码,如何在Linux中强制用户在下次登录时更改密码?

由于安全方面的考虑&#xff0c;系统中的用户需要定期更新其密码。在本文中&#xff0c;我们将看到如何强制用户下次登录系统时更改其密码。列出用户首先让我们看一下系统中可用的用户。$ cut -d: -f1 /etc/passwd运行上面的代码给我们以下结果-mailnewsuucpproxywww-databacku…

C# 键盘钩子

C# 键盘钩子 1、键盘钩子&#xff1a; 通过代码将键盘的事件屏蔽掉&#xff0c;达到锁屏的效果。&#xff08;参考地址&#xff1a;https://zhidao.baidu.com/question/135132386108196965.html&#xff09; 2、代码如下&#xff1a; public class Hook : IDisposable{public d…

js中字符串和数组的使用

函数&#xff1a; 函数在调用的时候&#xff0c;会形成一个私有作用域&#xff0c;内部的变量不会被外面访问&#xff0c;这种保护机制叫闭包。这就意味着函数调用完毕&#xff0c;这个函数形成的栈内存会被销毁。 但有时候我们不希望他被销毁。 函数归属谁跟它在哪调用没有关…

Spring REST:异常处理卷。 1个

目录 Spring REST&#xff1a;异常处理卷。 1个 Spring REST&#xff1a;异常处理卷。 2 Spring REST&#xff1a;异常处理卷。 3 大家好&#xff0c;是时候继续在我的博客中发布新文章了。 因此&#xff0c;我很高兴地宣布&#xff0c;我计划编写一系列技术文章。 在当前文…

vue/cli3 配置vux

安装各插件 试过 安装“必须安装”的部分亦可 1、安装vuex npm install vuex --save-dev 2、在项目里面安装vux【必须安装】 npm install vux --save 3、安装vux-loader【必须安装】 npm install vux-loader --save-dev 4、安装less-loader&#xff08;这个是用以正确编译less源…

鼠标右键 移动选定的文件夹到指定位置_怎么把电脑桌面上的文件移动到更加安全的地方...

我们在使用电脑的时候习惯于把各种文档以及其他文件资料随手保存到电脑桌面上&#xff0c;这样操作可以方便以后对这些文档和文件资料的使用、管理&#xff0c;但是由于默认状态下桌面文件位于C盘中&#xff0c;这些文件资料不仅会占用掉C盘的很大的存储空间&#xff0c;并且日…

非常精简的Linux线程池实现(一)——使用互斥锁和条件变量

线程池的含义跟它的名字一样&#xff0c;就是一个由许多线程组成的池子。 有了线程池&#xff0c;在程序中使用多线程变得简单。我们不用再自己去操心线程的创建、撤销、管理问题&#xff0c;有什么要消耗大量CPU时间的任务通通直接扔到线程池里就好了&#xff0c;然后我们的主…

linux vim 执行shell命令行,Linux中vim和shell

在Linux系统中一切皆文件&#xff0c;配置服务其实就是在修改其配置文件的参数&#xff0c;而在日常文件中肯定少不了的就是编辑文档&#xff0c;这就离不开vim&#xff0c;而vim之所以能够得到广大厂商的青睐与用户的认可&#xff0c;原因在于vim编辑器中有三种模式&#xff1…

JS之setTimeOut与clearTimeOut

小练习1&#xff1a;针对HTML&#xff0c;分别使用 setTimeout 和 setInterval 实现以下功能&#xff1a; 点击按钮时&#xff0c;开始改变 fade-obj 的透明度&#xff0c;开始一个淡出&#xff08;逐渐消失&#xff09;动画&#xff0c;直到透明度为0在动画过程中&#xff0c…

运行时的Java 8参数名称

Java 8将引入一种更容易的方法来发现方法和构造函数的参数名称。 在Java 8之前&#xff0c;找到参数名称的方法是在编译阶段打开调试符号&#xff0c;这会在生成的类文件中添加有关参数名称的元信息&#xff0c;然后提取复杂的信息&#xff0c;需要处理字节码。获取参数名称。…

python 可执行文件_如何通过Python函数运行的可执行文件的终端...

我想抑制运行可执行文件的函数产生的所有终端输出. 我试图通过使用每次调用函数时临时重新定义stdout和stderr的上下文管理器来抑制Python函数的输出.这会抑制函数中的print调用产生的终端输出,但是当函数调用产生终端输出的可执行文件时,它似乎不起作用. 那么,如何抑制Python函…

嵌入式linux系统文件,嵌入式Linux文件系统知多少

Nand/Nor Flash在嵌入式Linux产品中&#xff0c;通常使用的存储介质为Nand Flash和Nor Flash&#xff0c;而手机、相机等产品通常使用eMMC、SD Card作为存储介质&#xff0c;导致这种差异的原因主要是成本考量。Nand Flash和Nor Flash具有低成本、高密度存储的优势。但是&#…

三分钟上手Highcharts简易甘特图

根据业务需求&#xff0c;找到了这个很少使用的图形&#xff0c;话不多说&#xff0c;看看该如何使用。首先要引入支持文件&#xff1a;可根据链接下载。 exporting.js&#xff1a;https://img.hcharts.cn/highcharts/modules/exporting.js xrange.js&#xff1a;https://img.h…

WEB语义化

WEB语义化让机器读懂内容&#xff0c;HTML就带有一定「语义」的标签&#xff0c;比如段落&#xff0c;标题&#xff0c;表格和图片等。让机器读懂内容&#xff0c;那么两种方案&#xff1a;第一种让机器变得更人工智能化&#xff0c;也就是现在大火的AI。第二种是人们去发布认可…

Jetty 9.1上的Java WebSockets(JSR-356)

最终发布了Jetty 9.1 &#xff0c;将Java WebSockets&#xff08;JSR-356&#xff09;引入了非EE环境。 这真是个好消息&#xff0c;今天的帖子将介绍如何将这个出色的新API与Spring Framework一起使用。 JSR-356定义了基于注释的简洁模型&#xff0c;以允许现代Java Web应用程…

如何用python画组合图形_python结合G2绘制精美图形

$.getJSON(top10.json, function (data) { var Frame G2.Frame; var frame new Frame(data); var chart new G2.Chart({ id: c1, width: 500, height: 400 }); chart.source(frame, { pct: {alias: 年化相对收益率(%)}, }); // 去除 X 轴标题 chart.axis(name, { title: nul…

edup无线网卡驱动安装linux,UBUNTU_15.0.4 usb无线网卡驱动安装方法

前言&#xff1a;为了摆脱网线的束缚&#xff0c;我买了个无线网卡&#xff1b; widnows 上好用&#xff0c;易安装。linux 上&#xff0c;按照自带教程上去做&#xff0c;没有成功。后来在搜索了多篇 解决问题的文章。 再加上自己的方法&#xff0c;终于完成了。貌似信号还可以…

LeetCode Golang 9.回文数

9. 回文数 第一种办法 &#xff1a;itoa 转换为字符串进行处理&#xff1a; package mainimport ("strconv""fmt" )//判断一个整数是否是回文数。回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。…

关于使用JQ scrollTop方法进行滚动定位

没图我说个锤子&#xff0c;先来个自拍镇楼。 又到了每周周五总结时间。我广州刘德华又来讲故事了。这一周没啥任务&#xff0c;就一个任务&#xff0c;产品口头交代了两句&#xff0c;也没有psd没有设计图没有样式。自由发挥&#xff0c;你自己敲代码做个作品出来。 what&…