经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
从零开始实现放置游戏(七)——实现挂机战斗(5)RMS系统后台参数校验
来源:cnblogs  作者:丶谦信  时间:2019/6/28 8:33:30  对本文有异议

  前面几章实现了在RMS系统中进行数据的增删查改以及通过Excel批量导入。但仍有遗留的问题,比如在新增或编辑时,怪物的生命值、护甲等数据我们可以输入负值,这种数据是不合理且没有意义的。本章我们就实现服务端对参数的校验。

一、添加依赖项

  在rms模块的pom.xml中,添加校验组件的依赖项(注意:之前的组件我们都引用了最新版本。但因hibernate-validator的最新版本6.xx+中引用的el-api.jar有冲突,无法用maven插件启动,所以这里使用5.1.1版本):

  1. <!-- 参数校验 -->
  2. <dependency>
  3. <groupId>org.hibernate</groupId>
  4. <artifactId>hibernate-validator</artifactId>
  5. <version>5.1.1.Final</version>
  6. </dependency>

  这个组件本身提供了一些注解,@NotNull, @NotBlank, @Min等等,来对模型进行校验,但错误提示不够好,默认通用的错误提示无法明确知道是哪个字段报错。如果为每个字段添加一个提示语,又非常繁琐,所以我们这里稍加改动,在util模块做一个通用的校验工具包。

  在util模块的pom.xml中添加依赖:

  1. <dependency>
  2. <groupId>javax.validation</groupId>
  3. <artifactId>validation-api</artifactId>
  4. <version>2.0.1.Final</version>
  5. <scope>provided</scope>
  6. </dependency>

二、添加自定义注解及提示信息

  以非空校验为例,在util模块中新建包com.idlewow.util.validation.annotaion,在此包下新建一个注解类NotBlank.java如下:

  1. package com.idlewow.util.validation.annotation;
  2. import com.idlewow.util.validation.validator.NotBlankValidator;
  3. import javax.validation.Constraint;
  4. import javax.validation.Payload;
  5. import javax.validation.ReportAsSingleViolation;
  6. import java.lang.annotation.Documented;
  7. import java.lang.annotation.ElementType;
  8. import java.lang.annotation.Retention;
  9. import java.lang.annotation.RetentionPolicy;
  10. import java.lang.annotation.Target;
  11. @Documented
  12. @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
  13. @Retention(RetentionPolicy.RUNTIME)
  14. @ReportAsSingleViolation
  15. @Constraint(validatedBy = NotBlankValidator.class)
  16. @NotNull
  17. public @interface NotBlank {
  18. String field() default "";
  19. String message() default "{field.not.blank.message}";
  20. Class<?>[] groups() default {};
  21. Class<? extends Payload>[] payload() default {};
  22. @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
  23. @Retention(RetentionPolicy.RUNTIME)
  24. @Documented
  25. @interface List {
  26. NotBlank[] value();
  27. }
  28. }

  注解有了,还需要一个对应的检验器,新建包com.idlewow.util.validation.validator,并在此包下新建类NotBlankValidator如下:

  1. package com.idlewow.util.validation.validator;
  2. import com.idlewow.util.validation.annotation.NotBlank;
  3. import javax.validation.ConstraintValidator;
  4. import javax.validation.ConstraintValidatorContext;
  5. public class NotBlankValidator implements ConstraintValidator<NotBlank, CharSequence> {
  6. public NotBlankValidator() {
  7. }
  8. public void initialize(NotBlank annotation) {
  9. }
  10. @Override
  11. public boolean isValid(CharSequence charSequence, ConstraintValidatorContext constraintValidatorContext) {
  12. if (charSequence == null) {
  13. return false;
  14. } else {
  15. return charSequence.toString().trim().length() > 0;
  16. }
  17. }
  18. }

  另外,在对模型进行校验时,不同场景下的需求不同。比如,在新增时,因为主键由数据库自增,无需添加主键;编辑时,则必须指定主键ID,对其进行非空校验。因此,我们在com.idlewow.util.validation包下在新建一个对校验分组的类ValidateGroup:

  1. package com.idlewow.util.validation;
  2. import javax.validation.groups.Default;
  3. import java.io.Serializable;
  4. public class ValidateGroup implements Serializable {
  5. public interface Create extends Default {
  6. }
  7. public interface Update extends Default {
  8. }
  9. }

  最后,我们在util模块的resource资源目录下添加提示信息的资源文件ValidationMessages.properties,

  1. #common invalid message
  2. field.not.blank.message={field}不能为空
  3. field.not.null.message={field}不能为NULL
  4. field.size.message={field}的长度应为{min}至{max}之间
  5. field.min.message={field}不能小于{value}
  6. field.max.message={field}不能大于{value}
  7. field.range.message={field}的大小应为{min}至{max}之间
  8. field.positive.message={field}必须是正数
  9. field.negative.message={field}必须是负数

三、参数校验注解的使用

  首先,我们需要在需要校验的模型上加上注解,此处以怪物模型为例:

  1. package com.idlewow.mob.model;
  2. import com.idlewow.common.model.BaseModel;
  3. import com.idlewow.util.validation.annotation.NotBlank;
  4. import com.idlewow.util.validation.annotation.NotNull;
  5. import com.idlewow.util.validation.annotation.Positive;
  6. import lombok.Data;
  7. import lombok.EqualsAndHashCode;
  8. import java.io.Serializable;
  9. @Data
  10. @EqualsAndHashCode(callSuper = true)
  11. public class MapMob extends BaseModel implements Serializable {
  12. @NotBlank(field = "主键id", groups = ValidateGroup.Update.class)
  13. private String id;
  14. @NotBlank(field = "怪物名称")
  15. private String name;
  16. @NotBlank(field = "地图id")
  17. private String mapId;
  18. @NotBlank(field = "地图名称")
  19. private String mapName;
  20. @NotNull(field = "阵营")
  21. private Integer faction;
  22. @NotNull(field = "怪物种类")
  23. private Integer mobClass;
  24. @NotNull(field = "怪物类型")
  25. private Integer mobType;
  26. @Positive(field = "等级")
  27. private Integer level;
  28. @Positive(field = "生命值")
  29. private Integer hp;
  30. @Positive(field = "伤害")
  31. private Integer damage;
  32. @Positive(field = "护甲")
  33. private Integer amour;
  34. }

  模型注解添加完毕,我们在BaseController中添加一个通用的校验方法,方便在各个Controller中调用:

  1. public abstract class BaseController {
  2. ......
  3. ......
  4. @Autowired
  5. protected Validator validator;
  6. ......
  7. ......
  8. protected CommonResult validate(Object object, Class... classes) {
  9. Set<ConstraintViolation<Object>> set = validator.validate(object, classes);
  10. if (set != null && set.size() > 0) {
  11. ConstraintViolation constraintViolation = set.iterator().next();
  12. return CommonResult.fail(constraintViolation.getMessage());
  13. }
  14. return CommonResult.success();
  15. }
  16. }

  在MapMobController的新增和编辑方法中,添加校验逻辑,

  1. @Controller
  2. @RequestMapping("/manage/map_mob")
  3. public class MapMobController extends BaseController {
  4. ……
  5. ……
  6. @ResponseBody
  7. @RequestMapping(value = "/add", method = RequestMethod.POST)
  8. public Object add(@RequestBody MapMob mapMob) {
  9. try {
  10. CommonResult commonResult = this.validate(mapMob, ValidateGroup.Create.class);
  11. if (!commonResult.isSuccess())
  12. return commonResult;
  13. mapMob.setCreateUser(this.currentUserName());
  14. mapMobManager.insert(mapMob);
  15. return CommonResult.success();
  16. } catch (Exception ex) {
  17. logger.error(ex.getMessage(), ex);
  18. return CommonResult.fail();
  19. }
  20. }
  21. ……
  22. ……
  23. @ResponseBody
  24. @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
  25. public Object edit(@PathVariable String id, @RequestBody MapMob mapMob) {
  26. try {
  27. if (!id.equals(mapMob.getId())) {
  28. return CommonResult.fail("id不一致");
  29. }
  30. CommonResult commonResult = this.validate(mapMob, ValidateGroup.Update.class);
  31. if (!commonResult.isSuccess())
  32. return commonResult;
  33. mapMob.setUpdateUser(this.currentUserName());
  34. mapMobManager.update(mapMob);
  35. return CommonResult.success();
  36. } catch (Exception ex) {
  37. logger.error(ex.getMessage(), ex);
  38. return CommonResult.fail();
  39. }
  40. }
  41. }

四、运行效果

  

小结

  本章实现了对请求参数的后台校验,当然也可以在前端提前进行校验,但后端的校验一般必不可少。

  源码下载地址:https://idlestudio.ctfile.com/fs/14960372-384755438

欢 迎 催 更!

原文链接:http://www.cnblogs.com/lyosaki88/p/11098193.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号