springboot前后端数据交互,springbootthymeleaf数据交互
00-1010前言1。数据格式1.1。Json消息1.2。Xml消息2。接口规范2.1。响应消息规范2.2。请求数据规范3。参数验证3.1。简单参数验证3.2。3.2.1复杂参数验证。正则表达式验证3.2.2。用户定义的验证注释的摘要。
目录
SpringBoot非常适合Web应用程序开发,我们可以使用它轻松构建一个Web服务。在对Spring Boot的介绍中,我们用它实现了一个非常简单的界面并输出Hello World!让我们模拟一个真实的场景来学习SpringBoot应用开发。
00-1010在实际项目场景中,前后分离几乎是项目的标配。随着全栈时代的逐渐离去,后端负责业务逻辑处理,前端负责数据展示,已经成为一种固定的开发模式。一般来说,后端提供的数据接口可能有Json和XML两种数据形式。用哪个往往会和公司的工程师文化有关。
00-1010对于SpringBoot,它会默认使用Json作为响应消息格式。让我们用一个简单的例子来测试它:
首先,我们创建一个UserController来处理前端Web请求。
@ Controller @ request mapping(/sys/user )公共类user Controller { @ request mapping( log in )@ response body公共MapString,String login() { MapString,String hashMap=new hashMap();HashMap.put(msg ,登录成功);返回hashMap}}}这个例子相信大多数用过SpringMVC的人都会很熟悉。定义一个简单的控制器和等效的映射。与通常返回Url的控制器不同,这里我们使用@ResponseBody注释,表示这个接口响应是纯数据,没有任何接口显示。有关请求的相应地址,请参见以下输出:
显然,我们得到了想要的结果,一个标准的Json字符串,是不是很简单?
对于上面的代码,还可以进一步优化。由于所有Restful接口只返回数据,我们可以直接在类级别添加@ResponseBody注释。在大多数情况下,@Controller和@ResponseBody会再次一起使用,所以我们使用@RestController注释来替换它们,从而更简洁地实现功能。
@ rest controller @ request mapping(/sys/user )公共类user controller { @ request mapping( log in )公共MapString,String login() { MapString,String hashMap=new hashMap();HashMap.put(msg ,登录成功);返回hashMap}}
前言
大多数情况下,Json可以满足我们的需求,但是还有一些特定的场景需要使用XML消息,比如微信微信官方账号开发。不过,不用担心,切换到XML message只需要稍加改动。按如下方式添加相关依赖项:
Com。faster XML . Jackson . data format 3360 Jackson-data format-XML 33602 . 8 . 8 然后就可以开始测试了。这里我们用一个模拟的HTTP请求工具(Postman)来帮助我们测试接口,如何使用就不多说了。只需显示上图:
在上面的测试示例中,我们将Accept指定为text/xml,因此SpringBoot将以xml形式返回数据。
00-1010对于每个公司来说,它都会定义自己的数据规范。一个统一标准的数据规范对于系统维护非常重要,也大大提高了开发效率。
>
2.1. 响应报文规范
一般来说,接口响应至少需要告诉使用方三项信息:状态码、描述、数据。其中,数据不是每个接口必须的,如果只是一个简单修改的动作,可能就没有必须返回数据了。下面我们定义一个 Result 类来封装我们的响应报文。
public class Result { private int code; private String msg; private Object data; public Result(ResultCode resultCode, Object data) { this(resultCode); this.data = data; } public Result(ResultCode resultCode) { this.code = resultCode.getCode(); this.msg = resultCode.getMsg(); } ...}
同时,定义一个枚举类来维护我们的状态码:
public enum ResultCode { SUCCESS(0, "请求成功"), WARN(-1, "网络异常,请稍后重试"); private int code; private String msg; ResultCode(int code, String msg) { this.msg = msg; } public int getCode() { return code; } public String getMsg() { return msg; }}
这样,我们的响应数据规范已基本建立。将上面代码中返回 Map 修改为返回 Result,按照指定规范返回数据,得到结果如下。
2.2. 请求数据规范
响应报文格式我们已经定义好了,那么请求数据我们如何接收呢?一般来说,请求与响应会使用相同的报文形式,即,如果响应为Json,那么请求也建议使用Json。如果想要为上面的登录请求添加输入参数,需要完成以下几步:
首先,我们定义好用户实体:
public class User { private String username; private String password; ...}
然后,直接在映射方法里面使用该实体进行参数接收,并将接收到的参数直接返回:
@RestController@RequestMapping("/sys/user")public class UserController { @RequestMapping("login") public Result login(@RequestBody User loginUser) { return new Result(ResultCode.SUCCESS, loginUser); }}
调出我们的Postman,填写正确的Url,选择POST方式发送请求,选择Body,将 Content-Type 设置成 application/json,填入 Json 格式的请求数据,点击 Send 即可得到如下结果。
数据接收非常成功,但在上面的响应报文中,存在着了一个非常严重的问题,那就是用户的密码也随同用户信息一起返回给了客户端,显然这并不是一种正确的做法。我们需要对其进行一次过滤,由于 SpringBoot 默认使用 Jackson 作为 Json 序列化工具,如果想要过滤掉响应中的某些字段,只需在过滤字段对应的 get 方法上加上 @JsonIgnore 注解即可。但这样又会引发另外一个问题,那就是请求中的字段也被过滤掉了,对于这种问题,可以采用抽离请求参数模型的方式进行处理,即自定义一套参数接收的 Model,比如,接收用户登录的会使用 UserModel 来进行参数接收,这样使得请求参数模型与数据库映射实体完全分离,在一定程度上提升了系统的安全性。
@RequestMapping("login")public Result login(@RequestBody UserModel userModel) { User user = new User(); user.setUsername(userModel.getUsername()); user.setPassword(userModel.getPassword()); return new Result(ResultCode.SUCCESS, user);}
替换成 Model 对象后,我们就可以在数据库映射实体 User 上增加 @JsonIgnore 注解忽略该字段的序列化,而不影响请求参数的输入。
3. 参数校验
出于系统健壮性的考虑,一般来说,我们需要对所有的参数进行必要性校验,如:登录请求时,如果没有用户名,程序应该立即驳回该请求。上面请求参数模型(Model)的抽象也使得我们对数据校验更加方便,当然主要还是依赖于 SpringBoot 的 Validate 功能的强大支持。
3.1. 简单参数校验
对于登录接口来说,用户名与密码都是必输的,那么我们现在为其添加上对应的参数校验,无需 if-else 判断,简单的几个注解就可以帮助我们完成所有的工作。
@RequestMapping("login")public Result login(@RequestBody @Valid UserModel userModel) { ...}---public class UserModel { private String username; private String password; @NotBlank(message = "用户名不能为空") public String getUsername() { return username; } @NotBlank(message = "密码不能为空") public String getPassword() { return password; } ...}
在上面的示例中,我们为请求参数的 Model 对象加上了 @Valid 注解,并在 Model 类中,对需要校验字段的 get 方法上添加相应的校验注解。效果如下:
3.2. 复杂参数校验
3.2.1. 正则表达式校验
如果用户的登录名为手机号,那么就需要对登录名的格式做进一步的校验,下面使用正则表达式来校验手机号的合法性。
@NotBlank(message = "用户名不能为空")@Pattern( regexp = "1(([38]\d)(5[^4&&\d])(4[579])(7[0135678]))\d{8}", message = "手机号格式不合法")public String getUsername() { return username;}
3.2.2. 自定义校验注解
在系统使用过程中,有很多地方需要对手机号的格式进行校验,如:注册、验证码发送等。但校验手机号的正则表达式又过于复杂,如果多处编写,一旦运营商增加某个号段,对程序的维护人员来说就是一个噩耗。这时,可以使用自定义校验注解来代替这些常用的校验。
手机号校验实现类 PhoneValidator:
public class PhoneValidator implements ConstraintValidator<Phone, String> { private Pattern pattern = Pattern.compile("1(([38]\d)(5[^4&&\d])(4[579])(7[0135678]))\d{8}"); @Override public void initialize(Phone phone) { } @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { return pattern.matcher(value).matches(); }}
手机号校验注解 Phone:
@Constraint(validatedBy = PhoneValidator.class)@Target({ElementType.METHOD, ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Phone { String message() default "手机号格式不合法"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};}
Model 上的使用:
@Phonepublic String getUsername() { return username;}
这样的话,如果因为某些不可抗拒因素导致校验规则的变动,只需要修改一处理即可,维护成本大大降低。
项目的 github 地址:https://github.com/qchery/funda
总结
到此这篇关于SpringBoot项目实战之数据交互篇的文章就介绍到这了,更多相关SpringBoot数据交互内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。