首页 > 其他分享 >参数校验与国际化:提高代码稳定性和可维护性的重要方法

参数校验与国际化:提高代码稳定性和可维护性的重要方法

时间:2023-12-15 09:12:07浏览次数:29  
标签:国际化 String 校验 可维护性 参数 注解 message public

在我们日常的工作中,参数校验是一项非常重要的任务。它能够帮助我们确保代码的稳定性和可靠性,避免因为参数错误而导致的意外情况发生。参数校验通常包括对输入参数的合法性、格式的检查等。而为了提高代码的可维护性和可重用性,我们可以使用一些常见的参数校验方法。

另外,国际化也是一项非常重要的功能,尤其是在跨国项目中。通过国际化的配置,我们可以根据用户的语言环境,自动切换显示的语言,提供更好的用户体验。在参数校验中,我们也可以使用国际化配置来返回相应的提示信息,使得提示信息能够适应不同的语言环境。

  • RequestParam参数校验
  • NotEmpty等注解参数校验
  • 实体类增加参数校验
  • CustomException,自定义异常对参数异常进行国际化定制
  • NotEmptyField,自定义注解实现对参数异常进行国际化定制

好的,让我们一步一步来介绍参数校验的方法。除了上述提到的方法,如果还有一些其他的优秀方法可以用来进行参数校验,也可以提醒我一下!

RequestParam参数校验

RequestParam本身就有对参数进行的基础校验,比如required表示是否参数必填。可以通过在方法参数上使用@RequestParam注解来实现参数校验。以下是示例代码:

@GetMapping("/hello-not-required")
public String sayHelloByNotRequired(@RequestParam(required = false, name = "who") String who) {
    if (StrUtil.isBlank(who)) {
        who = "World";
    }
    return StrUtil.format("Hello, {}!", who);
}

如果不传递参数,也不会有任何问题,这里不做演示就可以了,非常简单。

NotEmpty等注解参数校验

默认message

然而,虽然RequestParam只能指示参数是否被携带,但它并不负责检验参数值是否为空。因此,我们可以通过与NotEmpty注解结合使用来进行判断。

@GetMapping("/hello-required")
  public String sayHelloByRequired(@RequestParam @NotEmpty String who) {
    return StrUtil.format("Hello, {}!", who);
  }

当访问http://localhost:8080/demo/hello-required?who=时,我们的程序是报错的,因为who字段不能为空

image

自定义message

如果你仔细阅读了NotEmpty注解的文档,你会发现它允许自定义报错提示信息。因此,我们可以尝试自定义提示信息,以满足我们的需求。

@GetMapping("/hello-required-message")
public String sayHelloByRequiredWithMessage(@RequestParam @NotEmpty(message = "who must be not null") String who) {
  return StrUtil.format("Hello, {}!", who);
}

我再来为你演示一下,除了NotEmpty注解,还有许多其他已经内置的注解可供使用。我就不一一列举了,你可以自行探索更多的注解。

image

实体类增加参数校验

除了上面提到的简单校验方式,我们在实际开发中更常使用的是通过JSON传递参数,并使用实体类接收参数。下面是相关代码示例:

@PostMapping("/hello-required-message-object")
public String sayHelloByRequiredWithMessageForObject(@RequestBody @Valid MyTest test) {
  return StrUtil.format("Hello, {}!", test);
}
public class MyTest {

  @NotEmpty(message = "NotEmpty.message")
  private String test;

  public String getTest() {
    return test;
  }

  public void setTest(String test) {
    this.test = test;
  }
}

加长优化语句:为了方便演示,我特意更换了一些提示信息,以便更清晰地展示给大家。接下来,我们再仔细观察一下。

image

自定义异常

其实在工作中,校验参数是一个常见的任务。我们通常会使用代码进行各种校验,因为我们对参数的要求远远超出了简单的非空检查。除了非空检查,我们还需要进行其他等值校验等。因此,如果在代码中进行校验,我们可以选择抛出异常或直接返回错误信息。举个例子,我可以使用自定义异常来说明这一点:

@PostMapping("/hello-required-message-i18n")
public String sayHelloByRequiredWithMessageFori18n() {
  throw new CustomException("notBlank.message");
}

代码经过优化,已经去除了多余的逻辑,直接通过抛出异常来处理。让我来演示一下。

image

虽然在出错时会有报错信息返回,但是这些错误信息并不完全符合业务返回数据的格式。为了解决这个问题,我们需要定义一个全局异常处理类来统一处理异常情况。

@RestControllerAdvice
public class GlobalExceptionHandler {

  @Autowired
  private MessageSource messageSource;
  
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex, Locale locale) {
      String errorMessage = messageSource.getMessage(ex.getMessage(), null, locale);
      ErrorResponse errorResponse = new ErrorResponse(500, errorMessage);
      return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

ErrorResponse是我单独定义的错误描述类,我就不写了,因为每个项目都会有自己的返回类。

国际化信息

让我们进一步探讨一下关于国际化信息的定制。首先,为了实现这一目标,你需要在应用程序中进行相关的配置,具体来说,就是在application.yaml文件中进行必要的设置。

server:
  port: 8080
  servlet:
    context-path: /demo
spring:
  messages:
    baseName: i18n/messages
    encoding: UTF-8
  mvc:
    locale: zh_CN

请注意,baseName在这里表示路径,而最后的messages并不代表包的含义,而是文件的前缀。如果无法找到messages_zh_CN文件,则会尝试查找messages_zh文件,如果还找不到,则会查找messages文件。因此,请不要再创建一个名为messages的包。

image

当所有准备工作完成后,我们可以检查演示结果是否已经改变了字段信息。

image

自定义注解

现在基本上已经存在了全局异常处理机制,不过我们还需要进一步优化。现在让我们来讨论一下自定义注解的使用。首先,我们注意到错误信息无法给出具体的字段值。显然,我们不能每次都手动写上每个字段的名称并提示不能为空。为了解决这个问题,我们需要自定义一个注解来实现自动化的校验。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotEmptyField {
    String message() default "";
}

有了注解后,下一步就是通过切面来获取并处理这个注解。接下来,我们来编写相应的代码来实现这个功能:


@Aspect
@Component
public class NotEmptyFieldAspect {
  @Autowired
  private MessageSource messageSource;

    @Around("within(com.xkcoding..*)")
    public Object validateNotEmptyField(ProceedingJoinPoint joinPoint) throws Throwable {
      // 获取目标方法的参数列表
      Object[] args = joinPoint.getArgs();

      // 遍历参数列表
      for (Object arg : args) {
        // 获取参数实体类的属性
        Field[] fields = arg.getClass().getDeclaredFields();

        // 遍历属性列表
        for (Field field : fields) {
          // 判断属性是否被 @NotEmptyField 注解修饰
          if (field.isAnnotationPresent(NotEmptyField.class)) {
            // 获取注解信息
            NotEmptyField annotation = field.getAnnotation(NotEmptyField.class);
            field.setAccessible(true);
            // TODO: 进一步处理逻辑
            if (ObjectUtil.isEmpty(field.get(arg))) {
              String message = messageSource.getMessage(annotation.message(), null, Locale.getDefault());
              throw new CustomException(field.getName() + message);
            }
            // 输出属性和注解信息
            System.out.println("属性:" + field.getName());
            System.out.println("注解信息:" + annotation.message());
            System.out.println("值:" + field.get(arg));
          }
        }
      }

      // 调用目标方法
      Object result = joinPoint.proceed();

      return result;
    }
}

我只是简单地写了一下实现逻辑,并没有进行优化操作,所以以上代码仅供参考。现在让我们来看一下外层代码:

  @PostMapping("/hello-required-message-i18n-object")
  public String sayHelloByRequiredWithMessageFori18nObject(@RequestBody @Valid MyTestForAspect myTestForAspect) {
    return "";
  }

当我们完成所有的准备工作之后,让我们来观察一下演示情况:

image

总结

在我们的工作中,参数校验是一项不可或缺的重要任务。因此,本文只是初步探讨了可以进行优化的方面,而并未详细阐述如何完美地进行优化。如果我遗漏了一些解决方案,也欢迎大家提供宝贵的建议和提醒。我的目的只是提供一些思路和引发讨论,以期能够共同进步。

标签:国际化,String,校验,可维护性,参数,注解,message,public
From: https://www.cnblogs.com/guoxiaoyu/p/17893081.html

相关文章

  • Vue2 校验不通过的表单,赋正确的值后,再次校验结果不变
    前言在工作中遇到了这个问题,多次排查,耗费了不少时间才解决这个问题。问题的解决很简单,但发现根本原因还是有点困难,因此在此做个记录,以防忘记。问题发现步骤例如有以下AntDesignVue表单<a-form-modelref="formRef":model="model"><a-form-model-itemlabel="姓名"pr......
  • MIRO相关的增强,EXTENSION,校验替代
    EXTENSION:  校验替代: BADI:INVOICE_UPDATE点击保存按钮或模拟过账,校验直接message报错,替代改内存 ......
  • 【转载】SpringBoot2.x使用Assert校验(非单元测试)
    参考https://blog.csdn.net/yangshangwei/article/details/123105926环境环境版本操作windows10JDK11Springboot2.3.12.RELEASE注意引入的包为importorg.springframework.util.Assert;介绍对象和类型断言函数说明notNull()假设对......
  • CRC校验计算
    循环冗余校验(英语:Cyclicredundancycheck,通称“CRC”)是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正......
  • element-ui表单校验|标红提示
    elementUI表单校验1.表单上加rules{object}(常用)增加普通校验规则<el-form:model="form":rules="rules"ref="form"><el-form-itemlabel="姓名:":label-width="formLabelWidth"prop="uname"><el-in......
  • 【APP小程序测试】APP抓包Frida反代理绕过和证书校验绕过
    前期准备逍遥模拟器Burp(抓包)测试APPfridawiresharkr0capture反代理和证书校验绕过解决app证书校验无法抓包问题使用工具:FridaFirda是一款易用的跨平Hook工具,Java层到Native层的Hook无所不能,是一种动态的插桩工具,可以插入代码到原生App的内存空间中,动态的......
  • 国内项目国际化后金额处理方案
     目标现状及问题目标:已有的国内项目,需要部署国际化。需要考虑币种、金额货币精度、多语言、汇率、税等一系列问题。这里主要说的就是其中金额精度的处理。现状:日常国内项目里,界面输入的金额是元,然后数据库存储以及与其他系统交互都是用的分,也是就固定的货币精度系数100。......
  • 幂等性校验
    1.什么是幂等性   幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同   在计算机中编程中,一个幂等操作的特点是 其任意多次执行所产生的影响均与一次执行的影响相同   幂等函数或幂等方法是指可以使用相同参......
  • 前端优化之路:git commit 校验拦截
     【前言】 前面在git分支规范那篇文章里,介绍了commit提交规范,如下图 但是想要做到高效落地执行,就需要做些别的功课,先展示下成果图没错,对不符合规范的commit进行了拦截,符合才可以成功提交。   【前期准备】 需要了解githooks,它是git的钩子,就像vue拥有自己的......
  • vant组件一个文本框添加多项校验
    下图为用户密码校验表单,需要对密码是否为空,密码长度,以及密码强度进行校验。但是“密码格式不正确!”这个校验信息并不是我想要的,我想在isPassWordStrength方法中区分开密码长度提示和密码强度提示,方便用户知道具体是什么问题导致校验不通过。<van-fieldrequiredv-model......