基于springboot实现http响应异常信息国际化
背景
国际化是指在设计软件,将软件与特定语言及地区脱钩的过程。当软件被移植到不同的语言及地区时,软件本身不用做内部工程上的改变或修正。
本文提到的异常响应信息国际化是指:前端向后台发起请求,后台在处理逻辑中发生异常,把异常信息返回给前端,返回的异常信息应该支持国际化,能够对应特定的语言、地区等环境。例如,中文语言环境下返回的异常信息应该是中文的,英文语言环境下返回的则是对应的英文。
javaweb项目中,不管是对底层的数据操作,还是业务层的处理过程,还是控制层的处理,都不可避免的会遇到各种可预知的(业务异常主动抛出)、不可预知的异常需要处理。一般dao层、service层的异常都会直接抛出,最后由controller统一进行处理,并对前端请求进行异常响应。针对此处的业务异常应该做到设计合理,统一格式,并且支持国际化。
springboot是一个开源的Java/Java EE的应用程序框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。利用springboot提供的API库,我们能方便地做到全局异常统一拦截,并且Spring提供了完善的国际化支持,在此基础上,我们能方便地做到全局异常信息的国际化。
原来存在的方案:
局部的异常信息国际化:程序在抛出异常时手动设置好国际化之后的异常message。
此种方案代码耦合性强,代码繁琐,处理逻辑过程中抛出异常时还得额外考虑对异常进行国际化操作,使得代码逻辑无法很好的集中在业务逻辑的处理。示意图如图1.1。

半异常信息国际化:程序中未采用配置文件来记录国际化资源,而是直接在程序中写死了固定的异常值,每条异常值记录分别对应着不同的异常编号、某几种语言的异常信息。
这是目前比较常见的方式,写起来方便,不需要在程序抛出异常时做国际化,只需在全局异常拦截中做统一的异常返回。但是,这种方式支持的异常信息比较单一,不能轻易添加多种语言的支持,只能改动现有程序的代码。示意图如图1.2。

使用编程语言自带的异常本地化接口。
不少后台语言提供了异常信息本地化接口,比如java提供的java.lang.Throwable#getLocalizedMessage方法,但是这种方式只能获取到本地语言相关的对应的信息,并不能很好的支持多种语言,以及多种语言间的自由切换。
现在的方案
此方案结合异常码、字符串占位符和资源文件的特点及优势。异常码可理解为一个异常信息的ID,具有唯一性,必要性;异常信息资源文件中的值可包含占位符(格式为{n}),处理异常时可用实际值替换,达到异常信息的进一步具体化,但不是必须的。资源文件就是内容为“异常码=提心信息”的记录的文件。
方案具体描述如下:
首先,在springboot项目中定义系统的http请求统一返回的数据格式,此处我们的定义包含三个属性: code(业务异常状态码)、message(异常提示信息)、data(无异常时返回的数据体)。对异常信息国际化主要体现在message属性,也就是返回前端给用户展示的异常提示信息。code属性用于确定唯一的异常。其次定义需要抛出的业务异常,其中主要包括code(异常码)和params(用于替换异常信息字符串占位符{n}的实际值)属性。
在项目路径下定义异常信息的资源文件,文件内容包含多条记录,每条记录为键值对的形式,即key=value。对需要实现的语言种类分别提供一份对应的文件,这些文件名除默认信息外,均包含语言(地区信息),文件中包含中key是一致的,value为相应语言的字符串组成。如果添加语言的支持,只需要添加一份对应的资源文件即可。以下包含默认、英文环境和简体中文环境下对应的异常提示信息国际化资源文件,如图2.1

利用springboot的提供的接口定义统一拦截器,并且注入http请求上下文和资源获取器,在拦截器中对应用抛出的异常进行捕获,针对上述特定的异常做国际化处理。
其国际化处理逻辑如下:根据http请求传入的语言信息指定特定的语言(地区)环境,如没有传入语言信息,则采用应用默认的语言配置;据此读取上述编写好的对应的异常信息资源文件,并依据捕获的异常中的code(异常码)查到到对应的字符串,将params实际值替换掉字符串中的占位符,完成后即为返回给前端的异常提示信息。

在controller、service和dao层中根据程序逻辑抛出相应异常,其中异常码应该在资源文件中已定义。示例代码如下图2.3

整体流程图如下图2.4

demo
以下是一个demo,其中提供了必要的代码注释,以便于理解。
自定义异常结构,包含code和params

异常资源文件定义

全局异常拦截

代码逻辑中抛出异常

请求响应示例
请求1:http://127.0.0.1:8080/demo?lang=en&msg=a
返回:
请求2:http://127.0.0.1:8080/demo?lang=zh_CN&msg=a
返回:
请求3:http://127.0.0.1:8080/demo?lang=en&msg=c
返回:
请求4:http://127.0.0.1:8080/demo?lang=zh_CN&msg=c
返回:
总结
- 此方案能较好地处理异常信息的国际化,能自如地添加资源文件,不需要改动此方案的现有代码,这也使得程序耦合性降低;
- 统一的异常格式定义、全局异常拦截极大程度上减少了代码耦合性,大大简化了团队编码中对异常逻辑的处理,能减少重复性编码,有利于提高工作效率;
- 现有方案未能较好地支持异常信息中特定值的支持,此方案利用设置占位符的方式,较好地做到了支持,灵活方便;
- springboot支持的国际化实现中默认提供了缓存支持,性能良好。
参考
(文中配图有空再改!!)
基于springboot实现http响应异常信息国际化的更多相关文章
- springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本 get请求报400 异常信息为 The valid characters are defined in RFC 7230 and RFC 3986
1.springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本而之前用的是tomcat7 get请求报400 异常信息为 The valid characters are ...
- c#执行插入sql 时,报错:异常信息:超时时间已到。在操作完成之前超时时间已过或服务器未响应
问题:c#执行插入sql 时,报错:异常信息:超时时间已到.在操作完成之前超时时间已过或服务器未响应 解决: SqlCommand cmd = new SqlCommand(); cmd.Comman ...
- springboot 统一管理异常信息
新建ResponseEntityExceptionHandler的继承类:(依然,需要入口类扫描) /** * @author sky * @version 1.0 */ @ControllerAdv ...
- 基于SpringBoot搭建应用开发框架(二) —— 登录认证
零.前言 本文基于<基于SpringBoot搭建应用开发框架(一)——基础架构>,通过该文,熟悉了SpringBoot的用法,完成了应用框架底层的搭建. 在开始本文之前,底层这块已经有了很 ...
- shiro,基于springboot,基于前后端分离,从登录认证到鉴权,从入门到放弃
这个demo是基于springboot项目的. 名词介绍: ShiroShiro 主要分为 安全认证 和 接口授权 两个部分,其中的核心组件为 Subject. SecurityManager. Re ...
- 基于springboot的web项目最佳实践
springboot 可以说是现在做javaweb开发最火的技术,我在基于springboot搭建项目的过程中,踩过不少坑,发现整合框架时并非仅仅引入starter 那么简单. 要做到简单,易用,扩展 ...
- 基于SpringBoot+AntDesign的快速开发平台,JeecgBoot 2.0.2 版本发布
Jeecg-Boot 是一款基于SpringBoot+代码生成器的快速开发平台! 采用前后端分离架构:SpringBoot,Ant-Design-Vue,Mybatis,Shiro,JWT. 强大的代 ...
- 搭建基于springboot轻量级读写分离开发框架
何为读写分离 读写分离是指对资源的修改和读取进行分离,能解决很多数据库瓶颈,以及代码混乱难以维护等相关的问题,使系统有更好的扩展性,维护性和可用性. 一般会分三个步骤来实现: 一. 主从数据库搭建 信 ...
- Shiro 核心功能案例讲解 基于SpringBoot 有源码
Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...
随机推荐
- ⑤ 设计模式的艺术-05.原型(Prototype)模式
场景 思考一下:克隆技术是怎么样的过程? 克隆羊多利大家还记得吗? javascript语言中的,继承怎么实现?那里面也有prototype,大家还记得吗? 原型模式 通过new产生一个对象需要非常繁 ...
- TED_Topic3:The hidden reason for poverty the world needs to address now
The hidden reason for poverty the world needs to address now By Gary Haugen # Background about our s ...
- Freemarker代码生成器原理说明
一.Freemarker基本原理: FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具. 它不是面向最终用 ...
- hdu 2119 Matrix(二分匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2119 Matrix Time Limit: 5000/1000 MS (Java/Others) ...
- ajax技术整理总结(1)
1.创建ajax对象 var xhr=new XMLHttpRequest(); 4.监听状态信息 xhr.onreadystatechange=function(){ //4接收完毕 ){ docu ...
- spring-boot-资源处理
WebMvcConfigurerAdapter 使用 1.实现 HandlerInterceptorAdapter 2.添加拦截器 重写WebMvcConfigurerAdapter中的addInte ...
- 高性能优秀的服务框架-dubbo介绍
先来了解一下这些年架构的变化,下面的故事是我编的.... "传统架构":很多年前,刚学完JavaWeb开发的我凭借一人之力就开发了一个网站,网站 所有的功能和应用都集中在一起,方便 ...
- Linux下的压缩解压缩
Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲t ...
- 利用__attribute__((section()))构建初始化函数表【转】
转自: https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652663356&idx=1&sn=7797629530 ...
- virsh 命令最新整理。 每个“;”之后是正解
1,migrate --domain --destURL --dname --live(热迁移) migrate lf 192.168.16.3 dname 2,managedsave domain ...