MessageFormat的具体使用(格式化消息)

news2024/11/18 0:42:12

文章目录

  • 1. 前言
  • 2. 先说结论
  • 3. 在结论上补充其他更加特殊情况
    • 1. 数字类型可以使用#字符来确认精度
    • 2. 数组类型转化需要注意
    • 3. 输出特殊字符
    • 4. 如何判断一个String是否有替换位
  • 4. 粗略原理

1. 前言

  1. 在工作中发现接口的返回报文,大部分公司通常都会封装一层,具体如下:

    // dto封装
    {
        "code": "错误码",
        "message": "错误信息",
        "data":"返回数据"
    }
    // 报错情况
    {
        "code": "DEMO00001",
        "message": "插入数据库失败,失败原因:{0}"
    }
    // 成功情况
    {
        "code": "success",
        "data": "返回数据"
    }
    

    这种返回的好处是在于排查定位问题,可快速找到对应的代码,因为错误码全局只能用一次不可重复使用,当报错的时候,可以根据这个唯一的错误码找到对应位置。

  2. 本篇文章当然不是说上述返回的dto,而是对报错情况返回的message特别感兴趣,比较好奇是如何文本替换,进行格式化处理的,查阅资料发现,jdk自带有MessageFormat消息格式化功能,接下来就让我们一起探讨。

2. 先说结论

  1. 一般使用:

    String str = "str:test-format:{0}-{1}";
    // 推荐此方法,直接使用静态方法
    // 结果:str:test-format:Hello-world
    System.out.println(MessageFormat.format(str, "Hello", "world"));
    
    String str2 = "str2:test-format:{0}-{1}";
    // 也可new对象,但不如上面第一种方便
    MessageFormat messageFormat = new MessageFormat(str2);
    // 结果:str2:test-format:Hello-world
    System.out.println(messageFormat.format(str2, "Hello", "world"));
    
  2. 特殊使用:

    1. MessageFormat可对时间、日期、数字进行更加特殊格式转化

    2. 一般使用MessageFormat只会简单的{0},如 str = “test:{0}”,但其实MessageFormat支持的不仅仅是{0},{0}只是其中一个模板写法,其全称模板如下: { ArgumentIndex , FormatType , FormatStyle }

    3. ArgumentIndex:数字0,1,2

    4. FormatType:格式化类型,支持:

      "", // 默认格式
      "number", // 数字
      "date", // 日期
      "time", // 时间
      "choice" // 没研究,不考虑
      
      // 例子
      String str = "test:{0,number}"
      String str2 = "test:{0,date}"
      
    5. FormatStyle:格式化风格,支持

      // 数字支持
      "currency", // 通货格式,通俗就是钱
      "percent", // 百分数
      "integer" // 整型
      
      // 日期支持
      "short",  // yy-MM-dd
      "medium", //yyyy-MM-dd
      "long", // yyyy年 M月dd日
      "full" // yyyy年 M月dd日 星期几
      
      // 时间支持
      "short",  // 下午h:mm
      "medium", //hh:mm:ss
      "long", // 下午hh时mm分ss秒
      "full" // 下午hh时mm分ss秒 CST
      
    6. 例子

      // 数字
      String str = "test:{0,number,currency}";
      // 结果:test:¥1.20
      System.out.println(MessageFormat.format(str,1.2));
      
      String str2 = "test:{0,number,percent}";
      // 结果:test:120%
      System.out.println(MessageFormat.format(str2,1.2));
      
      String str3 = "test:{0,number,integer}";
      // 结果:test:1
      System.out.println(MessageFormat.format(str3,1.2));
      
      // 日期
      String str4 = "test:{0,date,short}";
      // 结果:22-12-17
      System.out.println(MessageFormat.format(str4, new Date()));
      
      String str5 = "test:{0,date,medium}";
      // 结果:2022-12-17
      System.out.println(MessageFormat.format(str5, new Date()));
      
      String str6 = "test:{0,date,long}";
      // 结果:2022年12月17日
      System.out.println(MessageFormat.format(str6, new Date()));
      
      String str7 = "test:{0,date,full}";
      // 结果:2022年12月17日 星期六
      System.out.println(MessageFormat.format(str7, new Date()));
      
      
      // 时间
      String str4 = "test:{0,time,short}";
      // 结果:下午2:41
      System.out.println(MessageFormat.format(str4, new Date()));
      
      String str5 = "test:{0,time,medium}";
      // 结果:14:41:52
      System.out.println(MessageFormat.format(str5, new Date()));
      
      String str6 = "test:{0,time,long}";
      // 结果:下午02时41分52秒
      System.out.println(MessageFormat.format(str6, new Date()));
      
      String str7 = "test:{0,time,full}";
      // 结果:下午02时41分52秒 CST
      System.out.println(MessageFormat.format(str7, new Date()));
      

3. 在结论上补充其他更加特殊情况

1. 数字类型可以使用#字符来确认精度

String str = "test:{0,number,#.##}";
// 结果:test:1.23
System.out.println(MessageFormat.format(str, 1.23456));

String str2 = "test:{0,number,#.##}";
// 结果:test:1.2
// 不会自动补零
System.out.println(MessageFormat.format(str2, 1.2));

2. 数组类型转化需要注意

// 第一种情况
Object[] typeParams = {"A", "B", "C"};
// 只有一个要替换格式
String str2 = "str2:test-format:{0}";
// 结果:str2:test-format:A
// 因为MessageFormat.format的第二个参数本身就是可变参数
// 又刚刚好,传递了一个数组,默认会认为数组里面的内容,是替换参数的数量以及值
// 不会觉得你传递的typeParams是一个整体要输出
System.out.println(MessageFormat.format(str2, typeParams));

// 第二种情况
Object[] typeParams = {"A", "B", "C"};
String str2 = "str2:test-format:{0}-{1}";
// 结果:str2:test-format:类型有-[Ljava.lang.Object;@1218025c
System.out.println(MessageFormat.format(str2, "类型有", typeParams));
// 结果:str2:test-format:类型有-[A, B, C]
System.out.println(MessageFormat.format(str2, "类型有", Arrays.toString(typeParams)));

3. 输出特殊字符

// 输出双引号,使用 \ 转义符
String str2 = "str2:test-format:\"a\"-\"{0}\"-\"c\"";
// 结果:str2:test-format:"a"-"b"-"c"
System.out.println(MessageFormat.format(str2, "b"));

// 输出{}号,使用 ' 单引号
String str2 = "str2:test-format:'{'a'}'-'{'{0}'}'-'{'c'}'";
// 结果:str2:test-format:{a}-{b}-{c}
System.out.println(MessageFormat.format(str2, "b"));

// 输出单引号,使用 '' 两个单引号代表输出一个单引号
String str2 = "str2:test-format:''a''-''{0}''-''c''";
// 结果:str2:test-format:'a'-'b'-'c'
System.out.println(MessageFormat.format(str2, "b"));

4. 如何判断一个String是否有替换位

MessageFormat.getFormats方法是将得到一个数组数组个数即是字符串中{0}{1}有几个替换位

String str1 = "{0}-{1}-{2}-{3}";
MessageFormat messageFormat = new MessageFormat(str1);
// 结果:4
System.out.println(messageFormat.getFormats().length);

String str2 = "test";
MessageFormat messageFormat2 = new MessageFormat(str2);
// 结果:0
System.out.println(messageFormat2.getFormats().length);

4. 粗略原理

  1. MessageFormat的底层源码太多了,这里就粗略简述其的现实方式,不细扣细节了,其实现原理:就是对输入的字符串一个个扫描,匹配是否有{ } 括号,做相关处理。
    在这里插入图片描述
    为什么需要知道去掉替换符的字符串呢?
    其实是配合offsets偏移量使用的,比如第一个替换符位置是第五位,传入参数是A,那么:pattern.substring(0, 5) + A
    就达到了:实际上就是字符串拼接,但效果就是替换
    在这里插入图片描述在这里插入图片描述

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

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

相关文章

2022-LCLR-DIFFDOCK: DIFFUSION STEPS, TWISTS, AND TURNS FOR MOLECULAR DOCKING

2022-LCLR-DIFFDOCK: DIFFUSION STEPS, TWISTS, AND TURNS FOR MOLECULAR DOCKING Paper: https://arxiv.org/abs/2210.01776 Code: https://github.com/gcorso/DiffDock 预测小分子配体与蛋白质的结合结构(称为分子对接)是药物设计的关键。最近的深度学习方法将对接视为一个回…

GB/T 20984-2022《信息安全技术 信息安全风险评估方法》解读

前言 近年来,信息安全风险评估工作逐步在国家基础信息网络及重要行业信息系统中普遍推行,信息安全风险评估是信息安全保障工作的基础和重要环节,日前, GB/T 20984-2022 《信息安全技术 信息安全风险评估方法》发布,将…

oracle学习篇(四)

oracle学习篇(四) 1 PL/SQL异常处理 1.1 预定义异常 1.1.1 内容 oracle里面已经存在的异常 如果是自定义异常,一般写的编号是20000-20999之间1.1.2 处理异常语法 exceptionwhen 异常类型1 then输出异常类型信息1;when 异常信息2 then输出异常类型信息2;--以上都…

MR案例:学生排序(单字段排序、多字段排序)

文章目录一、提出任务二、完成任务(一)准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录(二)实现步骤1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、创建学生实体类5、创建学生映射器类5、创建学生归并器类6…

JS中操作<select>标签选的值

JS中操作<select>标签选的值 <select>标签是一种表单控件&#xff0c;用来创建下拉列表。在<select> 标签内可用 <option> 标签定义下拉列表中的可用选项。下面给出一个基本下拉列表示例&#xff1a; <!DOCTYPE html> <html lang"zh&q…

Codeforces Round #838 (Div. 2)

A. Divide and Conquer 题目链接&#xff1a;Problem - A - Codeforces 样例输入&#xff1a; 4 4 1 1 1 1 2 7 4 3 1 2 4 1 15样例输出&#xff1a; 0 2 1 4题意&#xff1a;一个数组是好的当且仅当所有的元素和是一个偶数&#xff0c;现在给我们一个初始数组&#xff0c;我…

Android---组件化

1、单体应用 所有代码写在一个工程里。不同业务写到各自模块&#xff0c;以包名来区分。 弊端 1、无论包名做的再好&#xff0c;随着项目扩大&#xff0c;项目失去层次感&#xff0c;接受吃力。 2、报名作为约束&#xff0c;太弱了。一不注意就会出现不同业务之间之间相互调…

【算法数据结构专题】「限流算法专项」带你认识常用的限流算法的技术指南(分析篇)

限流 限流的目的是通过对并发访问/请求进行限速&#xff0c;或者对一个时间窗口内的请求进行限速来保护系统&#xff0c;一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理 限流一词常用于计算机网络之中&#xff0c;定义如下&#xff1a; In computer networks, rate l…

接口测试(七)—— 参数化、数据库操作类封、接口自动化框架

目录 一、接口自动化测试框架 1、目录结构 二、封装iHRM登录 1、普通方式实现 2、登录接口对象层 3、登录接口测试用例层 4、封装断言方法 三、参数化 1、回顾UnitTest参数化 1.1 原始案例 1.2 参数化实现 1.3 从json文件读取 2、登录接口参数化 2.1 组织数据文…

java8流操作之不常用但是很好用的隐藏api

前言 1、一些普通的方式就不再多说了&#xff0c;这里主要说一些不常用的&#xff0c;但是作用很大的api方式 2、如果想要细致了解可以参考 JAVA8的流操作&#xff0c;十分推荐 一、flatMap 1、这个api主要是用来推平流的&#xff0c;和map不一致&#xff0c;map是对象到对…

Python基础(十六):函数的初步认识

文章目录 函数的初步认识 一、函数的作用 二、函数的使用步骤 1、定义函数 2、调用函数 3、快速体验 三、函数的参数作用 四、函数的返回值作用 1、应用 五、函数的说明文档 1、语法 2、快速体验 3、函数嵌套调用 七、函数应用 1、打印图形 2、函数计算 八、总…

还在为多张Excel汇总统计发愁?Python 秒处理真香!

为什么越来越多的非程序员白领都开始学习 Python &#xff1f;他们可能并不是想要学习 Python 去爬取一些网站从而获得酷酷的成就感&#xff0c;而是工作中遇到好多数据分析处理的问题&#xff0c;用 Python 就可以简单高效地解决。本文就通过一个实际的例子来给大家展示一下 P…

新手传奇gm架设要学会的几个修改技巧

每个传奇gm对于架设一个服务器都有自己独立的看法和想法&#xff0c;一些人之所以会想着要架设一个传奇私服主要原因是自己在其他人的服力玩得不是那么舒心。所以想要按照自己的想法和思路打造一个适合自己的专属服务器进行游戏&#xff0c;其实这两者之间是有必然联系的&#…

毕业三年活得像个废物,转行网络安全,写给像我一样迷茫的人...

首先说说我吧&#xff0c;普通二本非科班商贸专业毕业&#xff0c;三年了&#xff0c;做过电商&#xff0c;做过新媒体&#xff0c;做过业务员&#xff0c;从躺平到摆烂&#xff0c;一开始还挺享受这样的生活的&#xff0c;毕竟每月4千工资&#xff0c;抛出吃住&#xff0c;剩个…

重学webpack系列(八) -- webpack的运行机制与工作原理

前面几个章节我们分别去探索了webpack的loader机制、plugin机制、devServer、sourceMap、HMR&#xff0c;但是你是否知道这些配置项是怎么去跟webpack本身执行机制挂钩的呢&#xff1f;这一章我们就来探索一下webpack的运行机制与工作原理吧。 webpack核心工作过程 我们打开w…

第十四章 文件操作

1.文件的基本操作 文件&#xff0c;对我们并不陌生&#xff0c;文件是数据源&#xff08;保存数据的地方&#xff09;的一种&#xff0c;比如大家经常使用的Word文档&#xff0c;TXT文件&#xff0c;excel文件…都是文件。文件最主要的作用就是保存数据&#xff0c;它既可以保…

用户虚拟地址空间管理-mm_struct

一、进程虚拟地址空间管理概览 二、mm_struct结构体的主要成员 atomic_t mm_users;共享同一个用户虚拟地址空间的进程的数量&#xff0c;也就是线程组包含的进程的数量atomic_t mm_count;内存描述符的引用计数struct vm_area_struct *mmap;虚拟内存区域链表struct rb_root mm_…

【java】课程设计--抽卡模拟器

文章目录工期安排自己实现菜单逻辑抽卡算法0.书写要求1.用户需求2.设计思想3.各个功能和算法描述4.系统调试中问题5.总结新知识怎么打开任务管理器改进&#xff08;进一步的设想&#xff09;交给她们实现1.注册登录2.读文件-显示查找内容暂时成功案例工期安排 1 自定义增加和删…

数据权限就该这么设计

在项目实际开发中我们不光要控制一个用户能访问哪些资源&#xff0c;还需要控制用户只能访问资源中的某部分数据。 控制一个用户能访问哪些资源我们有很成熟的权限管理模型即RBAC&#xff0c;但是控制用户只能访问某部分资源&#xff08;即我们常说的数据权限&#xff09;使用…

[附源码]Python计算机毕业设计红旗家具城管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…