往期热门文章:

1、项目终于用上了Spring状态机,非常优雅!


(相关资料图)

2、自从用了这款 IDEA 神器,领导都夸我代码写得好!

3、MyBatis的二级缓存,慎用!

4、8种专坑同事的 SQL 写法,性能降低100倍,不来看看?

5、最近火起的 Bean Searcher 与 MyBatis Plus 到底有啥区别?

一、前言

一个后端接口大致分为四个部分组成:接口地址(url)、接口请求方式(get、post等)、请求数据(request)、响应数据(response)。虽然说后端接口的编写并没有统一规范要求,而且如何构建这几个部分每个公司要求都不同,没有什么“一定是最好的”标准,但其中最重要的关键点就是看是否规范。

二、环境说明

因为讲解的重点是后端接口,所以需要导入一个 spring-boot-starter-web 包,而 lombok 作用是简化类,前端显示则使用了 knife4j,具体使用在 Spring Boot 整合 knife4j 实现 API 文档已写明。另外从 springboot-2.3 开始,校验包被独立成了一个 starter 组件,所以需要引入如下依赖:

org.springframework.boot spring-boot-starter-validation com.github.xiaoymin knife4j-spring-boot-starter 2.0.2 org.springframework.boot spring-boot-starter-web org.projectlombok lombok true

三、参数校验

3.1介绍

一个接口一般对参数(请求数据)都会进行安全校验,参数校验的重要性自然不必多说,那么如何对参数进行校验就有讲究了。一般来说有三种常见的校验方式,我们使用了最简洁的第三种方法:

业务层校验

Validator + BindResult 校验

Validator + 自动抛出异常

业务层校验无需多说,即手动在 Java 的 Service 层进行数据校验判断。不过这样太繁琐了,光校验代码就会有很多。

而使用 Validator+ BindingResult 已经是非常方便实用的参数校验方式了,在实际开发中也有很多项目就是这么做的,不过这样还是不太方便,因为你每写一个接口都要添加一个 BindingResult 参数,然后再提取错误信息返回给前端(简单看一下)。

@PostMapping("/addUser")public String addUser(@RequestBody @Validated User user, BindingResult bindingResult) { // 如果有参数校验失败,会将错误信息封装成对象组装在BindingResult里 List allErrors = bindingResult.getAllErrors(); if(!allErrors.isEmpty()){ return allErrors.stream() .map(o->o.getDefaultMessage()) .collect(Collectors.toList()).toString(); } // 返回默认的错误信息 // return allErrors.get(0).getDefaultMessage(); return validationService.addUser(user);}

3.2 Validator + 自动抛出异常(使用)

内置参数校验如下:

首先,Validator可以非常方便的制定校验规则,并自动帮你完成校验。在入参里需要校验的字段加上注解,每个注解对应不同的校验规则,并可制定校验失败后的信息:

@Datapublic class User { @NotNull(message = "用户id不能为空") private Long id; @NotNull(message = "用户账号不能为空") @Size(min = 6, max = 11, message = "账号长度必须是6-11个字符") private String account; @NotNull(message = "用户密码不能为空") @Size(min = 6, max = 11, message = "密码长度必须是6-16个字符") private String password; @NotNull(message = "用户邮箱不能为空") @Email(message = "邮箱格式不正确") private String email;}

校验规则和错误提示信息配置完毕后,接下来只需要在接口仅需要在校验的参数上加上 @Valid 注解(去掉 BindingResult 后会自动引发异常,异常发生了自然而然就不会执行业务逻辑):

@RestController@RequestMapping("user")public class ValidationController { @Autowired private ValidationService validationService; @PostMapping("/addUser") public String addUser(@RequestBody @Validated User user) { return validationService.addUser(user); }}

现在我们进行测试,打开 knife4j 文档地址,当输入的请求数据为空时,Validator 会将所有的报错信息全部进行返回,所以需要与全局异常处理一起使用。

// 使用form data方式调用接口,校验异常抛出 BindException// 使用 json 请求体调用接口,校验异常抛出 MethodArgumentNotValidException// 单个参数校验异常抛出ConstraintViolationException// 处理 json 请求体调用接口校验失败抛出的异常@ExceptionHandler(MethodArgumentNotValidException.class)public ResultVO MethodArgumentNotValidException(MethodArgumentNotValidException e) { List fieldErrors = e.getBindingResult().getFieldErrors(); List collect = fieldErrors.stream() .map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.toList()); return new ResultVO(ResultCode.VALIDATE_FAILED, collect);}// 使用form data方式调用接口,校验异常抛出 BindException@ExceptionHandler(BindException.class)public ResultVO BindException(BindException e) { List fieldErrors = e.getBindingResult().getFieldErrors(); List collect = fieldErrors.stream() .map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.toList()); return new ResultVO(ResultCode.VALIDATE_FAILED, collect);}

3.3 分组校验和递归校验

分组校验有三个步骤:

定义一个分组类(或接口)

在校验注解上添加 groups 属性指定分组

Controller 方法的 @Validated 注解添加分组类

public interface Update extends Default{}@Datapublic class User { @NotNull(message = "用户id不能为空",groups = Update.class) private Long id; ......}@PostMapping("update")public String update(@Validated({Update.class}) User user) { return "success";}

如果Update不继承Default,@Validated({Update.class})就只会校验属于Update.class分组的参数字段;如果继承了,会校验了其他默认属于Default.class分组的字段。

对于递归校验(比如类中类),只要在相应属性类上增加@Valid注解即可实现(对于集合同样适用)

3.4 自定义校验

Spring Validation 允许用户自定义校验,实现很简单,分两步:

自定义校验注解

编写校验者类

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documented@Constraint(validatedBy = {HaveNoBlankValidator.class})// 标明由哪个类执行校验逻辑public @interface HaveNoBlank { // 校验出错时默认返回的消息 String message() default "字符串中不能含有空格"; Class[] groups() default { }; Class[] payload() default { }; /** * 同一个元素上指定多个该注解时使用 */ @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Documented public @interface List { NotBlank[] value(); }}

public class HaveNoBlankValidator implements ConstraintValidator { @Override public boolean isValid(String value, ConstraintValidatorContext context) { // null 不做检验 if (value == null) { return true; } // 校验失败 return !value.contains(" "); // 校验成功 }}

四、全局异常处理

参数校验失败会自动引发异常,我们当然不可能再去手动捕捉异常进行处理。但我们又不想手动捕捉这个异常,又要对这个异常进行处理,那正好使用SpringBoot全局异常处理来达到一劳永逸的效果!

4.1 基本使用

首先,我们需要新建一个类,在这个类上加上 @ControllerAdvice 或 @RestControllerAdvice 注解,这个类就配置成全局处理类了。

这个根据你的 Controller 层用的是 @Controller 还是 @RestController 来决定。

然后在类中新建方法,在方法上加上 @ExceptionHandler 注解并指定你想处理的异常类型,接着在方法内编写对该异常的操作逻辑,就完成了对该异常的全局处理!我们现在就来演示一下对参数校验失败抛出的 MethodArgumentNotValidException 全局处理:

package com.csdn.demo1.global;import org.springframework.validation.ObjectError;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;@RestControllerAdvice@ResponseBodypublic class ExceptionControllerAdvice { @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) { // 从异常对象中拿到ObjectError对象 ObjectError objectError = e.getBindingResult().getAllErrors().get(0); // 然后提取错误提示信息进行返回 return objectError.getDefaultMessage(); } /** * 系统异常 预期以外异常 */ @ExceptionHandler(Exception.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public ResultVO handleUnexpectedServer(Exception ex) { log.error("系统异常:", ex); // GlobalMsgEnum.ERROR是我自己定义的枚举类 return new ResultVO<>(GlobalMsgEnum.ERROR); } /** * 所以异常的拦截 */ @ExceptionHandler(Throwable.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public ResultVO exception(Throwable ex) { log.error("系统异常:", ex); return new ResultVO<>(GlobalMsgEnum.ERROR); }}

我们再次进行测试,这次返回的就是我们制定的错误提示信息!我们通过全局异常处理优雅的实现了我们想要的功能!

以后我们再想写接口参数校验,就只需要在入参的成员变量上加上 Validator 校验规则注解,然后在参数上加上 @Valid 注解即可完成校验,校验失败会自动返回错误提示信息,无需任何其他代码!

4.2 自定义异常

在很多情况下,我们需要手动抛出异常,比如在业务层当有些条件并不符合业务逻辑,而使用自定义异常有诸多优点:

自定义异常可以携带更多的信息,不像这样只能携带一个字符串。

项目开发中经常是很多人负责不同的模块,使用自定义异常可以统一了对外异常展示的方式。

自定义异常语义更加清晰明了,一看就知道是项目中手动抛出的异常。

我们现在就来开始写一个自定义异常:

package com.csdn.demo1.global;import lombok.Getter;@Getter //只要getter方法,无需setterpublic class APIException extends RuntimeException { private int code; private String msg; public APIException() { this(1001, "接口错误"); } public APIException(String msg) { this(1001, msg); } public APIException(int code, String msg) { super(msg); this.code = code; this.msg = msg; }}

然后在刚才的全局异常类中加入如下:

//自定义的全局异常@ExceptionHandler(APIException.class)public String APIExceptionHandler(APIException e) { return e.getMsg();}

这样就对异常的处理就比较规范了。当然还可以添加对 Exception 的处理,这样无论发生什么异常我们都能屏蔽掉然后响应数据给前端,不过建议最后项目上线时这样做,能够屏蔽掉错误信息暴露给前端,在开发中为了方便调试还是不要这样做。

另外,当我们抛出自定义异常的时候全局异常处理只响应了异常中的错误信息 msg 给前端,并没有将错误代码 code 返回。这还需要配合数据统一响应。

如果在多模块使用,全局异常等公共功能抽象成子模块,则在需要的子模块中需要将该模块包扫描加入,@SpringBootApplication(scanBasePackages = {"com.xxx"})。

五、数据统一响应

统一数据响应是我们自己自定义一个响应体类,无论后台是运行正常还是发生异常,响应给前端的数据格式是不变的!这里我包括了响应信息代码 code 和响应信息说明 msg,首先可以设置一个枚举规范响应体中的响应码和响应信息。

@Getterpublic enum ResultCode { SUCCESS(1000, "操作成功"), FAILED(1001, "响应失败"), VALIDATE_FAILED(1002, "参数校验失败"), ERROR(5000, "未知错误"); private int code; private String msg; ResultCode(int code, String msg) { this.code = code; this.msg = msg; }}

自定义响应体:

package com.csdn.demo1.global;import lombok.Getter;@Getterpublic class ResultVO { /** * 状态码,比如1000代表响应成功 */ private int code; /** * 响应信息,用来说明响应情况 */ private String msg; /** * 响应的具体数据 */ private T data; public ResultVO(T data) { this(ResultCode.SUCCESS, data); } public ResultVO(ResultCode resultCode, T data) { this.code = resultCode.getCode(); this.msg = resultCode.getMsg(); this.data = data; }}

最后需要修改全局异常处理类的返回类型:

@RestControllerAdvicepublic class ExceptionControllerAdvice { @ExceptionHandler(APIException.class) public ResultVO APIExceptionHandler(APIException e) { // 注意哦,这里传递的响应码枚举 return new ResultVO<>(ResultCode.FAILED, e.getMsg()); } @ExceptionHandler(MethodArgumentNotValidException.class) public ResultVO MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) { ObjectError objectError = e.getBindingResult().getAllErrors().get(0); // 注意哦,这里传递的响应码枚举 return new ResultVO<>(ResultCode.VALIDATE_FAILED, objectError.getDefaultMessage()); }}

最后,在 controller 层进行接口信息数据的返回:

@GetMapping("/getUser")public ResultVO getUser() { User user = new User(); user.setId(1L); user.setAccount("12345678"); user.setPassword("12345678"); user.setEmail("123@qq.com"); return new ResultVO<>(user);}

经过测试,这样响应码和响应信息只能是枚举规定的那几个,就真正做到了响应数据格式、响应码和响应信息规范化、统一化!

还有一种全局返回类如下:

@Data@AllArgsConstructor@NoArgsConstructorpublic class Msg { //状态码 private int code; //提示信息 private String msg; //用户返回给浏览器的数据 private Map data = new HashMap<>(); public static Msg success() { Msg result = new Msg(); result.setCode(200); result.setMsg("请求成功!"); return result; } public static Msg fail() { Msg result = new Msg(); result.setCode(400); result.setMsg("请求失败!"); return result; } public static Msg fail(String msg) { Msg result = new Msg(); result.setCode(400); result.setMsg(msg); return result; } public Msg(ReturnResult returnResult){ code = returnResult.getCode(); msg = returnResult.getMsg(); } public Msg add(String key,Object value) { this.getData().put(key, value); return this; }}

六、全局处理响应数据(可选择)

接口返回统一响应体 + 异常也返回统一响应体,其实这样已经很好了,但还是有可以优化的地方。要知道一个项目下来定义的接口搞个几百个太正常不过了,要是每一个接口返回数据时都要用响应体来包装一下好像有点麻烦,有没有办法省去这个包装过程呢?

当然是有的,还是要用到全局处理。但是为了扩展性,就是允许绕过数据统一响应(这样就可以提供多方使用),我们可以自定义注解,利用注解来选择是否进行全局响应包装。

首先,创建自定义注解,作用相当于全局处理类开关:

@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD}) // 表明该注解只能放在方法上public @interface NotResponseBody {}

其次,创建一个类并加上注解使其成为全局处理类。然后继承 ResponseBodyAdvice 接口重写其中的方法,即可对我们的 controller 进行增强操作,具体看代码和注释:

package com.csdn.demo1.global;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.core.MethodParameter;import org.springframework.http.MediaType;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;@RestControllerAdvice(basePackages = {"com.scdn.demo1.controller"}) // 注意哦,这里要加上需要扫描的包public class ResponseControllerAdvice implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter returnType, Class> aClass) { // 如果接口返回的类型本身就是ResultVO那就没有必要进行额外的操作,返回false // 如果方法上加了我们的自定义注解也没有必要进行额外的操作 return !(returnType.getParameterType().equals(ResultVO.class) || returnType.hasMethodAnnotation(NotResponseBody.class)); } @Override public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType, Class> aClass, ServerHttpRequest request, ServerHttpResponse response) { // String类型不能直接包装,所以要进行些特别的处理 if (returnType.getGenericParameterType().equals(String.class)) { ObjectMapper objectMapper = new ObjectMapper(); try { // 将数据包装在ResultVO里后,再转换为json字符串响应给前端 return objectMapper.writeValueAsString(new ResultVO<>(data)); } catch (JsonProcessingException e) { throw new APIException("返回String类型错误"); } } // 将原本的数据包装在ResultVO里 return new ResultVO<>(data); }}

重写的这两个方法是用来在 controller 将数据进行返回前进行增强操作,supports 方法要返回为 true 才会执行 beforeBodyWrite 方法,所以如果有些情况不需要进行增强操作可以在 supports 方法里进行判断。

对返回数据进行真正的操作还是在 beforeBodyWrite 方法中,我们可以直接在该方法里包装数据,这样就不需要每个接口都进行数据包装了,省去了很多麻烦。此时 controller 只需这样写就行了:

@GetMapping("/getUser")//@NotResponseBody //是否绕过数据统一响应开关public User getUser() { User user = new User(); user.setId(1L); user.setAccount("12345678"); user.setPassword("12345678"); user.setEmail("123@qq.com"); // 注意哦,这里是直接返回的User类型,并没有用ResultVO进行包装 return user;}

七、接口版本控制

7.1 简介

在SpringBoot项目中,如果要进行 restful 接口的版本控制一般有以下几个方向:

基于 path 的版本控制

基于 header 的版本控制

在 Spring MVC下,url 映射到哪个 method 是由 RequestMappingHandlerMapping 来控制的,那么我们也是通过 RequestMappingHandlerMapping 来做版本控制的。

7.2 Path 控制实现

首先定义一个注解:

@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface ApiVersion { // 默认接口版本号1.0开始,这里我只做了两级,多级可在正则进行控制 String value() default "1.0";}

ApiVersionCondition 用来控制当前 request 指向哪个 method:

public class ApiVersionCondition implements RequestCondition { private static final Pattern VERSION_PREFIX_PATTERN = Pattern.compile("v(\\d+\\.\\d+)"); private final String version; public ApiVersionCondition(String version) { this.version = version; } @Override public ApiVersionCondition combine(ApiVersionCondition other) { // 采用最后定义优先原则,则方法上的定义覆盖类上面的定义 return new ApiVersionCondition(other.getApiVersion()); } @Override public ApiVersionCondition getMatchingCondition(HttpServletRequest httpServletRequest) { Matcher m = VERSION_PREFIX_PATTERN.matcher(httpServletRequest.getRequestURI()); if (m.find()) { String pathVersion = m.group(1); // 这个方法是精确匹配 if (Objects.equals(pathVersion, version)) { return this; } // 该方法是只要大于等于最低接口version即匹配成功,需要和compareTo()配合 // 举例:定义有1.0/1.1接口,访问1.2,则实际访问的是1.1,如果从小开始那么排序反转即可// if(Float.parseFloat(pathVersion)>=Float.parseFloat(version)){// return this;// } } return null; } @Override public int compareTo(ApiVersionCondition other, HttpServletRequest request) { return 0; // 优先匹配最新的版本号,和getMatchingCondition注释掉的代码同步使用// return other.getApiVersion().compareTo(this.version); } public String getApiVersion() { return version; }}

PathVersionHandlerMapping 用于注入 Spring 用来管理:

public class PathVersionHandlerMapping extends RequestMappingHandlerMapping { @Override protected boolean isHandler(Class beanType) { return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class); } @Override protected RequestCondition getCustomTypeCondition(Class handlerType) { ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType,ApiVersion.class); return createCondition(apiVersion); } @Override protected RequestCondition getCustomMethodCondition(Method method) { ApiVersion apiVersion = AnnotationUtils.findAnnotation(method,ApiVersion.class); return createCondition(apiVersion); } private RequestConditioncreateCondition(ApiVersion apiVersion) { return apiVersion == null ? null : new ApiVersionCondition(apiVersion.value()); }}

WebMvcConfiguration 配置类让 Spring 来接管:

@Configurationpublic class WebMvcConfiguration implements WebMvcRegistrations { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new PathVersionHandlerMapping(); }}

最后,controller进行测试,默认是 v1.0,如果方法上有注解,以方法上的为准(该方法 vx.x 在路径任意位置出现都可解析)。

@RestController@ApiVersion@RequestMapping(value = "/{version}/test")public class TestController { @GetMapping(value = "one") public String query(){ return "test api default"; } @GetMapping(value = "one") @ApiVersion("1.1") public String query2(){ return "test api v1.1"; } @GetMapping(value = "one") @ApiVersion("3.1") public String query3(){ return "test api v3.1"; }}

7.3 header 控制实现

总体原理与 Path 类似,修改 ApiVersionCondition 即可,之后访问时在 header 带上 X-VERSION 参数即可。

public class ApiVersionCondition implements RequestCondition { private static final String X_VERSION = "X-VERSION"; private final String version ; public ApiVersionCondition(String version) { this.version = version; } @Override public ApiVersionCondition combine(ApiVersionCondition other) { // 采用最后定义优先原则,则方法上的定义覆盖类上面的定义 return new ApiVersionCondition(other.getApiVersion()); } @Override public ApiVersionCondition getMatchingCondition(HttpServletRequest httpServletRequest) { String headerVersion = httpServletRequest.getHeader(X_VERSION); if(Objects.equals(version,headerVersion)){ return this; } return null; } @Override public int compareTo(ApiVersionCondition apiVersionCondition, HttpServletRequest httpServletRequest) { return 0; } public String getApiVersion() { return version; }}

八、API接口安全

8.1 简介

APP、前后端分离项目都采用API接口形式与服务器进行数据通信,传输的数据被偷窥、被抓包、被伪造时有发生,那么如何设计一套比较安全的 API 接口方案至关重要,一般的解决方案有以下几点:

Token 授权认证,防止未授权用户获取数据

时间戳超时机制

URL 签名,防止请求参数被篡改

防重放,防止接口被第二次请求,防采集

采用 HTTPS 通信协议,防止数据明文传输

8.2 Token 授权认证

因为 HTTP 协议是无状态的,Token 的设计方案是用户在客户端使用用户名和密码登录后,服务器会给客户端返回一个 Token,并将 Token 以键值对的形式存放在缓存(一般是 Redis)中,后续客户端对需要授权模块的所有操作都要带上这个 Token,服务器端接收到请求后进行 Token 验证,如果 Token 存在,说明是授权的请求。

Token 生成的设计要求:

应用内一定要唯一,否则会出现授权混乱,A 用户看到了 B 用户的数据;

每次生成的Token一定要不一样,防止被记录,授权永久有效;

一般 Token 对应的是 Redis的key,value 存放的是这个用户相关缓存信息,比如:用户的 id;

要设置 Token 的过期时间:过期后需要客户端重新登录,获取新的 Token。如果Token有效期设置较短,会反复需要用户登录,体验比较差,我们一般采用 Token 过期后,客户端静默登录的方式,当客户端收到Token过期后,客户端用本地保存的用户名和密码在后台静默登录来获取新的Token,还有一种是单独出一个刷新 Token 的接口,但是一定要注意刷新机制和安全问题;

根据上面的设计方案要求,我们很容易得到 Token=md5(用户ID + 登录的时间戳 + 服务器端秘钥)这种方式来获得 Token。因为用户 ID 是应用内唯一的,登录的时间戳保证每次登录的时候都不一样,服务器端秘钥是配置在服务器端参与加密的字符串(即:盐),目的是提高 Token 加密的破解难度,注意一定不要泄漏。

8.3 时间戳超时机制

客户端每次请求接口都带上当前时间的时间戳 timestamp,服务端接收到 timestamp 后跟当前时间进行比对,如果时间差大于一定时间(比如:1 分钟),则认为该请求失效。时间戳超时机制是防御 DOS 攻击的有效手段。例如

http://url/getInfo?id=1&timetamp=1661061696

8.4 URL 签名

写过支付宝或微信支付对接的同学肯定对URL签名不陌生,我们只需要将原本发送给server端的明文参数做一下签名,然后在server端用相同的算法再做一次签名,对比两次签名就可以确保对应明文的参数有没有被中间人篡改过。例如

http://url/getInfo?id=1&timetamp=1559396263&sign=e10adc3949ba59abbe56e057f20f883e

签名算法过程

首先,对通信的参数按 key 进行字母排序放入数组中(一般请求的接口地址也要参与排序和签名,那么需要额外添加 url=http://url/getInfo 这个参数);

对排序完的数组键值对用&进行连接,形成用于加密的参数字符串;

在加密的参数字符串前面或者后面加上私钥,然后用 md5 进行加密,得到 sign,然后随着请求接口一起传给服务器。服务器端接收到请求后,用同样的算法获得服务器的 sign,对比客户端的 sign 是否一致,如果一致请求有效。

8.5 防重放

客户端第一次访问时,将签名 sign 存放到服务器的 Redis 中,超时时间设定为跟时间戳的超时时间一致,二者时间一致可以保证无论在 timestamp 限定时间内还是外 URL 都只能访问一次,如果被非法者截获,使用同一个 URL 再次访问,如果发现缓存服务器中已经存在了本次签名,则拒绝服务。

如果在缓存中的签名失效的情况下,有人使用同一个 URL 再次访问,则会被时间戳超时机制拦截,这就是为什么要求 sign 的超时时间要设定为跟时间戳的超时时间一致。拒绝重复调用机制确保 URL 被别人截获了也无法使用(如抓取数据)。

方案流程

客户端通过用户名密码登录服务器并获取 Token;

客户端生成时间戳 timestamp,并将 timestamp 作为其中一个参数;

客户端将所有的参数,包括 Token 和 timestamp 按照自己的签名算法进行排序加密得到签名 sign;

将 token、timestamp 和 sign 作为请求时必须携带的参数加在每个请求的URL后边,例:http://url/request?token=h40adc3949bafjhbbe56e027f20f583a&timetamp=1559396263&sign=e10adc3949ba59abbe56e057f20f883e

服务端对 token、timestamp 和 sign 进行验证,只有在 token 有效、timestamp 未超时、缓存服务器中不存在 sign 三种情况同时满足,本次请求才有效。

8.6 采用 HTTPS 通信协议

安全套接字层超文本传输协议 HTTPS,为了数据传输的安全,HTTPS 在 HTTP 的基础上加入了 SSL 协议,SSL 依靠证书来验证服务器的身份,并为客户端和服务器之间的通信加密。

HTTPS 也不是绝对安全的,比如中间人劫持攻击,中间人可以获取到客户端与服务器之间所有的通信内容。

九、总结

自此整个后端接口基本体系就构建完毕了。

通过 Validator + 自动抛出异常 来完成了方便的参数校验

通过 全局异常处理 + 自定义异常 完成了异常操作的规范

通过数据统一响应完成了响应数据的规范

多个方面组装非常优雅的完成了后端接口的协调,让开发人员有更多的经历注重业务逻辑代码,轻松构建后端接口

这里再说几点:

controller 做好 try-catch 工作,及时捕获异常,可以再次抛出到全局,统一格式返回前端

做好日志系统,关键位置一定要有日志

做好全局统一返回类,整个项目规范好定义好

controller 入参字段可以抽象出一个公共基类,在此基础上进行继承扩充

controlle r层做好入参参数校验

接口安全验证

转自:魅Lemon,

链接:blog.csdn.net/lemon_TT/article/details/108309900

往期热门文章:

1、别再重复造轮子了,一个 Spring 注解轻松搞定循环重试功能!

2、2023最新互联网公司时长排行榜出炉!

3、弃用 Nginx 后!它成为了最受欢迎 Web 服务器。。。

4、计算机会成为下一个土木吗?

5、干掉Maven和Gradle!推出更强更快更牛逼的新一代构建工具,炸裂!

6、大公司为什么禁止SpringBoot项目使用Tomcat?

7、快速交付神器:阿里巴巴官方低代码引擎开源了!

8、为什么 Spring和IDEA 都不推荐使用 @Autowired 注解

9、程序员的悲哀是什么?

10、被问懵了:MySQL 自增主键一定是连续的吗?

推荐内容

  • 天天速看:告别混乱代码:SpringBoot 后端接口规范
    天天速看:告别混乱代码:SpringBoot 后端接口规范

  • 世界短讯!公立医院提质 健康广州提速
    世界短讯!公立医院提质 健康广州提速

  • 世界观察:安卓10模拟器有哪些 安卓10模拟器
    世界观察:安卓10模拟器有哪些 安卓10模拟器

  • 【时快讯】认购基金有什么好处_新基金认购有什么好处
    【时快讯】认购基金有什么好处_新基金认购有什么好处

  • 苯乙烯燃烧(关于苯乙烯燃烧的基本详情介绍)-当前短讯
    苯乙烯燃烧(关于苯乙烯燃烧的基本详情介绍)-当前短讯

  • 高中译林版英语听力mp3下载_九年级上册英语听力mp3下载
    高中译林版英语听力mp3下载_九年级上册英语听力mp3下载

  • 全球贸易复苏之路崎岖不平 快消息
    全球贸易复苏之路崎岖不平 快消息

  • 当前热讯:8000万英镑!曼联再遭截胡,拜仁提高报价签凯恩,列维应该放手了
    当前热讯:8000万英镑!曼联再遭截胡,拜仁提高报价签凯恩,列维应该放手了

  • 每日热文:益客食品(301116):6月29日北向资金增持11.4万股
    每日热文:益客食品(301116):6月29日北向资金增持11.4万股

  • 世界聚焦:北京花滑新秀大奖赛将初试啼声 双人新组合亦亮相
    世界聚焦:北京花滑新秀大奖赛将初试啼声 双人新组合亦亮相

  • 【全球报资讯】埃弗顿官方:34岁队长科尔曼续约1年,将迎太妃糖生涯第15个赛季
    【全球报资讯】埃弗顿官方:34岁队长科尔曼续约1年,将迎太妃糖生涯第15个赛季

  • 墙纸撕不干净怎么处理(墙纸撕不干净怎么清除)
    墙纸撕不干净怎么处理(墙纸撕不干净怎么清除)

  • 08726_0872
    08726_0872

  • 丫丫解锁新玩具竹笼:一刻也没闲着-天天最资讯
    丫丫解锁新玩具竹笼:一刻也没闲着-天天最资讯

  • 天天即时:下半年股价有望
    天天即时:下半年股价有望"翻倍"股在此!比尔·盖茨、王孝安、丘栋荣已埋伏

  • 环球讯息:表示喜欢句子
    环球讯息:表示喜欢句子

  • 【全球新视野】蒙犹以为犯军令不可以乡里故而废法遂垂涕斩之翻译_此言孙可以为王父尸 子不可以为父尸 翻译
    【全球新视野】蒙犹以为犯军令不可以乡里故而废法遂垂涕斩之翻译_此言孙可以为王父尸 子不可以为父尸 翻译

  • 时讯:中国石油大学(华东)2023年广西理工(高校专项)招生计划
    时讯:中国石油大学(华东)2023年广西理工(高校专项)招生计划

  • 宝藏田野丨如何推进乡村振兴?这里有浙江答案
    宝藏田野丨如何推进乡村振兴?这里有浙江答案

  • 国家统计局:2022年全国文化及相关产业营收超16万亿元
    国家统计局:2022年全国文化及相关产业营收超16万亿元

  • 微头条丨房地产行业资金流出榜:万科A等5股净流出资金超3000万元
    微头条丨房地产行业资金流出榜:万科A等5股净流出资金超3000万元

  • 环球简讯:多家高校下月起停用微信支付,微信团队致歉:即刻修正
    环球简讯:多家高校下月起停用微信支付,微信团队致歉:即刻修正

  • 还珠格格44岁赵薇近照_因还珠格格成名
    还珠格格44岁赵薇近照_因还珠格格成名

  • 世界视讯!馨子演过的电视剧大全(馨子演过的电视剧)
    世界视讯!馨子演过的电视剧大全(馨子演过的电视剧)

  • 李家超:对香港经济全面复苏谨慎乐观 海外资金和投资正回港
    李家超:对香港经济全面复苏谨慎乐观 海外资金和投资正回港

  • 关于猫咪的文艺唯美句子(关于猫咪的文艺唯美句子 有哪些) 世界独家
    关于猫咪的文艺唯美句子(关于猫咪的文艺唯美句子 有哪些) 世界独家

  • 快讯:英伟达 RTX 4060 显卡解禁评测:性能提升约 22%
    快讯:英伟达 RTX 4060 显卡解禁评测:性能提升约 22%

  • 城乡公交二十年 沿途乡村看发展|当前热点
    城乡公交二十年 沿途乡村看发展|当前热点

  • 住建部部长倪虹:研究建立房屋体检、养老、保险三项制度
    住建部部长倪虹:研究建立房屋体检、养老、保险三项制度

  • 美拟扩大对华芯片限制,英伟达首席财务官:将令美产业永久丧失机会
    美拟扩大对华芯片限制,英伟达首席财务官:将令美产业永久丧失机会

  • 环球热讯:2023年兔年金银币价格表(2023年06月29日)
    环球热讯:2023年兔年金银币价格表(2023年06月29日)

  • 【环球报资讯】「图说」拦
    【环球报资讯】「图说」拦

  • 2023浙江温州市永嘉县事业单位引进高层次人才拟聘用对象公示(3)
    2023浙江温州市永嘉县事业单位引进高层次人才拟聘用对象公示(3)

  • 深圳前海微众银行是什么贷款_深圳前海微众银行是什么贷款(微众银行贷款查征信吗)
    深圳前海微众银行是什么贷款_深圳前海微众银行是什么贷款(微众银行贷款查征信吗)

  • 铁东法院开展禁毒宣传活动
    铁东法院开展禁毒宣传活动

  • 杜康:黄金跌势依旧,早盘1910现价直接空!-新资讯
    杜康:黄金跌势依旧,早盘1910现价直接空!-新资讯

  • 坚守一线,顶住“烤”验出“凉”招
    坚守一线,顶住“烤”验出“凉”招

  • 姜枣茶饮料的配方及工艺研究
    姜枣茶饮料的配方及工艺研究

  • 世界视点!红枣概念龙头上市公司一览(2023/6/29)
    世界视点!红枣概念龙头上市公司一览(2023/6/29)

  • 借出高利贷犯法吗 全球新视野
    借出高利贷犯法吗 全球新视野

  • 当前关注:经济日报:现代设施农业让增产走上快车道
    当前关注:经济日报:现代设施农业让增产走上快车道

  • 重点聚焦!淮安再明确:这些费用减免!
    重点聚焦!淮安再明确:这些费用减免!

  • 土地拍卖市场冷热不均,保证去化率是关键_今日快讯
    土地拍卖市场冷热不均,保证去化率是关键_今日快讯

  • 天天最新:OpenAI已在英国伦敦设立新的办事处 为公司在海外的第一个分部
    天天最新:OpenAI已在英国伦敦设立新的办事处 为公司在海外的第一个分部

  • 预产期超过多久算是正常_预产期超过多少天之内算正常
    预产期超过多久算是正常_预产期超过多少天之内算正常

  • 习近平签署国家主席令
    习近平签署国家主席令

  • 诱夜奖劝 诱夜
    诱夜奖劝 诱夜

  • 环球实时:建湖人,7月起高铁晚班公交正式开通!
    环球实时:建湖人,7月起高铁晚班公交正式开通!

  • 环球新资讯:有钱就是任性_对于有钱就是任性简单介绍
    环球新资讯:有钱就是任性_对于有钱就是任性简单介绍

  • 中国代表团在联合国人权理事会敦促有关国家保护移民权利_焦点要闻
    中国代表团在联合国人权理事会敦促有关国家保护移民权利_焦点要闻

  • 天天速看:告别混乱代码:SpringBoot 后端接口规范
    天天速看:告别混乱代码:SpringBoot 后端接口规范

  • 全球动态:空军某基地:划好“责任田” 理清“帮带账”
    全球动态:空军某基地:划好“责任田” 理清“帮带账”

  • 帕萨特提车第二天就严重抖动 车主:车子像是仿佛在蹦 天天观速讯
    帕萨特提车第二天就严重抖动 车主:车子像是仿佛在蹦 天天观速讯

  • 国新文化:6月29日融资买入736.72万元,融资融券余额2.2亿元
    国新文化:6月29日融资买入736.72万元,融资融券余额2.2亿元

  • 世界短讯!公立医院提质 健康广州提速
    世界短讯!公立医院提质 健康广州提速

  • PET铜箔板块异动拉升
    PET铜箔板块异动拉升

  • 怎么把pdf分页变成单页_pdf怎么分页成单张 天天资讯
    怎么把pdf分页变成单页_pdf怎么分页成单张 天天资讯

  • 中药板块盘初冲高
                 世界快看
    中药板块盘初冲高 世界快看

  • 今日聚焦!中韩亚运会选手年龄对比:最高龄选手27岁 最年轻选手年仅19
    今日聚焦!中韩亚运会选手年龄对比:最高龄选手27岁 最年轻选手年仅19

  • 世界视点!锂电池概念股盘初走高
    世界视点!锂电池概念股盘初走高

  • 世界快讯:国家统计局:非制造业商务活动指数继续保持扩张
    世界快讯:国家统计局:非制造业商务活动指数继续保持扩张

  • 天天快讯:减速器概念股延续涨势
    天天快讯:减速器概念股延续涨势

  • 每日报道:银河证券:7月关注具有长期增长动能的行业及企业
    每日报道:银河证券:7月关注具有长期增长动能的行业及企业

  • 开封后的果汁能喝一天吗?| 消保委亲测-全球时讯
    开封后的果汁能喝一天吗?| 消保委亲测-全球时讯

  • 【天天快播报】株硬入选湖南省首批新材料中试平台
    【天天快播报】株硬入选湖南省首批新材料中试平台

  • 世界观察:安卓10模拟器有哪些 安卓10模拟器
    世界观察:安卓10模拟器有哪些 安卓10模拟器

  • 今日讯!6月30日投资早报| 尚荣医疗澄清:在岗员工仅剩个位数为不实报道;英飞拓:董事长刘肇怀等拟减持不超5.01%公司股份 今日两只新股申购
    今日讯!6月30日投资早报| 尚荣医疗澄清:在岗员工仅剩个位数为不实报道;英飞拓:董事长刘肇怀等拟减持不超5.01%公司股份 今日两只新股申购

  • 船记:威少并不急于在自由市场做决定
    船记:威少并不急于在自由市场做决定

  • 【时快讯】认购基金有什么好处_新基金认购有什么好处
    【时快讯】认购基金有什么好处_新基金认购有什么好处

  • 天天日报丨央行二季度调查:居民购房意愿和房地产企业贷款需求双双下降
    天天日报丨央行二季度调查:居民购房意愿和房地产企业贷款需求双双下降

  • 苯乙烯燃烧(关于苯乙烯燃烧的基本详情介绍)-当前短讯
    苯乙烯燃烧(关于苯乙烯燃烧的基本详情介绍)-当前短讯

  • 南财研选快讯|中信证券:家居消费加码提档 城市更新内外兼修
    南财研选快讯|中信证券:家居消费加码提档 城市更新内外兼修

  • 全球快看点丨中信建投:持续看好算力基础设施板块,推荐光模块、ICT设备、IDC
    全球快看点丨中信建投:持续看好算力基础设施板块,推荐光模块、ICT设备、IDC

  • 上半年公募基金首募总额超5100亿元 同比下滑33%
                 全球看热讯
    上半年公募基金首募总额超5100亿元 同比下滑33% 全球看热讯

  • 环球最新:南财研选快讯|中信证券:预计下游厂商会加速三氯蔗糖等更安全的甜味剂对阿斯巴甜的替代
    环球最新:南财研选快讯|中信证券:预计下游厂商会加速三氯蔗糖等更安全的甜味剂对阿斯巴甜的替代

  • 酒企频跨界扩大消费群体
    酒企频跨界扩大消费群体

  • 今年以来A股IPO募资额超2100亿元 特色中型投行承销额跻身前列
    今年以来A股IPO募资额超2100亿元 特色中型投行承销额跻身前列

  • 当前快看:从巴黎航展看脱碳转型新浪潮
    当前快看:从巴黎航展看脱碳转型新浪潮

  • 世界观热点:多家公司携“高精尖”产品亮相国际数字能源展
    世界观热点:多家公司携“高精尖”产品亮相国际数字能源展

  • 樱花臂纹身手稿线条(杨戬纹身手稿)
    樱花臂纹身手稿线条(杨戬纹身手稿)

  • 高中译林版英语听力mp3下载_九年级上册英语听力mp3下载
    高中译林版英语听力mp3下载_九年级上册英语听力mp3下载

  • 老人私自立遗嘱给孙女能否有效
    老人私自立遗嘱给孙女能否有效

  • 假想防卫都是防卫过当的一种表现-新视野
    假想防卫都是防卫过当的一种表现-新视野

  • 一线调研看新局丨迈入“百星飞天”新阶段 吉林卫星产业集群效应显现
    一线调研看新局丨迈入“百星飞天”新阶段 吉林卫星产业集群效应显现

  • 全球贸易复苏之路崎岖不平 快消息
    全球贸易复苏之路崎岖不平 快消息

  • 皮海洲:“中国好前妻”的故事为何没有感动市场? 新消息
    皮海洲:“中国好前妻”的故事为何没有感动市场? 新消息

  • 环球热门:好夫涅妇啥意思?_好夫涅妇啥意思
    环球热门:好夫涅妇啥意思?_好夫涅妇啥意思

  • 当前热讯:8000万英镑!曼联再遭截胡,拜仁提高报价签凯恩,列维应该放手了
    当前热讯:8000万英镑!曼联再遭截胡,拜仁提高报价签凯恩,列维应该放手了

  • 新传企划(01284.HK)6月30日起招股 发售价每股发售股份0.84-0.92港元-天天播资讯
    新传企划(01284.HK)6月30日起招股 发售价每股发售股份0.84-0.92港元-天天播资讯

  • 世界短讯!海报|上海6月夜间消费总额已达427.46亿元,夜间经济综合实力指数排名继续保持全国第一
    世界短讯!海报|上海6月夜间消费总额已达427.46亿元,夜间经济综合实力指数排名继续保持全国第一

  • 世界今日报丨墙壁刮了腻子能贴瓷砖吗(刮了腻子粉的墙能贴瓷砖吗)
    世界今日报丨墙壁刮了腻子能贴瓷砖吗(刮了腻子粉的墙能贴瓷砖吗)

  • 【天天报资讯】中国开展长江流域水生态考核试点工作
    【天天报资讯】中国开展长江流域水生态考核试点工作

  • 高速雨天行车注意事项_雨天行车注意事项
    高速雨天行车注意事项_雨天行车注意事项

  • 每日热文:益客食品(301116):6月29日北向资金增持11.4万股
    每日热文:益客食品(301116):6月29日北向资金增持11.4万股

  • 环球时讯:中国电研(688128):6月29日北向资金减持3.27万股
    环球时讯:中国电研(688128):6月29日北向资金减持3.27万股

  • 三星i9050升级(三星i9050)
    三星i9050升级(三星i9050)

  • 世界聚焦:北京花滑新秀大奖赛将初试啼声 双人新组合亦亮相
    世界聚焦:北京花滑新秀大奖赛将初试啼声 双人新组合亦亮相

  • 下一个朱婷!王云璐不忍了,做出重大决定蔡斌无奈,郎平看人真准_热消息
    下一个朱婷!王云璐不忍了,做出重大决定蔡斌无奈,郎平看人真准_热消息

  • 栗子猪肾粥_关于栗子猪肾粥概略-每日消息
    栗子猪肾粥_关于栗子猪肾粥概略-每日消息

  • 曾磊(关于曾磊介绍)
    曾磊(关于曾磊介绍)

  • 【全球报资讯】埃弗顿官方:34岁队长科尔曼续约1年,将迎太妃糖生涯第15个赛季
    【全球报资讯】埃弗顿官方:34岁队长科尔曼续约1年,将迎太妃糖生涯第15个赛季

  • 全球最资讯丨淳常在结局(淳常在)
    全球最资讯丨淳常在结局(淳常在)

  • 快讯:做了对的事情反而被起诉?天理来了!雷军给同行好好上了一“课”
    快讯:做了对的事情反而被起诉?天理来了!雷军给同行好好上了一“课”

  • 墙纸撕不干净怎么处理(墙纸撕不干净怎么清除)
    墙纸撕不干净怎么处理(墙纸撕不干净怎么清除)

  • 世界速看:感官先生表达什么意思_感官先生表达的含义
    世界速看:感官先生表达什么意思_感官先生表达的含义

  • 电焊打眼睛的小妙招_电焊打眼睛的小妙招_天天快播
    电焊打眼睛的小妙招_电焊打眼睛的小妙招_天天快播

  • 08726_0872
    08726_0872

  • 消息!财政部:2021年全国政府采购规模为36399亿元
    消息!财政部:2021年全国政府采购规模为36399亿元

  • “中非”奇妙游Vlog丨连办三届,何以星沙?
    “中非”奇妙游Vlog丨连办三届,何以星沙?

  • 股票短线是多长时间(最新短线股票推荐)|环球新资讯
    股票短线是多长时间(最新短线股票推荐)|环球新资讯

  • 【环球新视野】缅甸突发!一公路桥梁被炸,致多人伤亡
    【环球新视野】缅甸突发!一公路桥梁被炸,致多人伤亡

  • 辉瑞与石药集团宣布达成中国本土化新冠口服抗病毒治疗药物战略合作
                 全球观焦点
    辉瑞与石药集团宣布达成中国本土化新冠口服抗病毒治疗药物战略合作 全球观焦点

  • 今日观点!背靠能源第一省 光伏强市的电不够用了?
    今日观点!背靠能源第一省 光伏强市的电不够用了?

  • 世界微动态丨再赴猕猴桃受灾区 专家组干了啥?
    世界微动态丨再赴猕猴桃受灾区 专家组干了啥?

  • 丫丫解锁新玩具竹笼:一刻也没闲着-天天最资讯
    丫丫解锁新玩具竹笼:一刻也没闲着-天天最资讯

  • 上海陆家嘴一场交流会,嘉宾和主持人侃侃而谈,股民全跑了?券商回应
    上海陆家嘴一场交流会,嘉宾和主持人侃侃而谈,股民全跑了?券商回应

  • 环球微头条丨中国反垄断新规出台:知识产权行使范围也有“禁区”
    环球微头条丨中国反垄断新规出台:知识产权行使范围也有“禁区”

  • 599元!小米电视EA32新款发布:用上四核CPU、双频Wi-Fi
    599元!小米电视EA32新款发布:用上四核CPU、双频Wi-Fi

  • 央行刚刚发布了三份调查问卷 折射出怎样的经济现状?
    央行刚刚发布了三份调查问卷 折射出怎样的经济现状?

  • 天天即时:下半年股价有望
    天天即时:下半年股价有望"翻倍"股在此!比尔·盖茨、王孝安、丘栋荣已埋伏

  • 视焦点讯!笔记本运行内存4g升8g_笔记本运行内存怎么升
    视焦点讯!笔记本运行内存4g升8g_笔记本运行内存怎么升

  • 环球播报:狗没拴绳被撞伤,主人被判担主责
    环球播报:狗没拴绳被撞伤,主人被判担主责

  • 关于大连一高校食堂放多台彩票机及大连一高校食堂放多台彩票机详情
    关于大连一高校食堂放多台彩票机及大连一高校食堂放多台彩票机详情

  • 当虹科技加入中国移动元宇宙产业联盟
                _环球动态
    当虹科技加入中国移动元宇宙产业联盟 _环球动态

  • 环球讯息:丽尚国潮:拟定增募资不超过7.3亿元
    环球讯息:丽尚国潮:拟定增募资不超过7.3亿元

  • 中邮理财、华夏理财“固收+权益”产品收益亮眼,部分重仓资管计划超99%|机警理财日报
                 最新消息
    中邮理财、华夏理财“固收+权益”产品收益亮眼,部分重仓资管计划超99%|机警理财日报 最新消息

  • 当前快报:易事特:拟与员工持股平台设钠离子电池公司
    当前快报:易事特:拟与员工持股平台设钠离子电池公司

  • 今日热门!方萍萍:黄金在1902一线多头主力以时间换空间的可能性比较大
    今日热门!方萍萍:黄金在1902一线多头主力以时间换空间的可能性比较大

  • 世界讯息:福州房地产中介协会倡议:暑期减免应届大学毕业生租房佣金
    世界讯息:福州房地产中介协会倡议:暑期减免应届大学毕业生租房佣金

  • 环球讯息:表示喜欢句子
    环球讯息:表示喜欢句子

  • 人代会定思路谋新篇,助力响水高质量发展
    人代会定思路谋新篇,助力响水高质量发展

  • 公募“中考”揭榜(一)|年内分红金额不足千亿 债基占比超八成扛大旗_看热讯
    公募“中考”揭榜(一)|年内分红金额不足千亿 债基占比超八成扛大旗_看热讯

  • 胡锡进:世卫要宣布无糖可乐等大量使用的阿斯巴甜致癌?这太震动了
    胡锡进:世卫要宣布无糖可乐等大量使用的阿斯巴甜致癌?这太震动了

  • 当前速看:盛视科技:中标约1.06亿元设备采购项目
    当前速看:盛视科技:中标约1.06亿元设备采购项目

  • 热议:晶科能源向保加利亚最大的光伏电站提供N型TOPCon双面组件
    热议:晶科能源向保加利亚最大的光伏电站提供N型TOPCon双面组件

  • 香港暂停进口瑞典一地区禽肉及禽类产品
    香港暂停进口瑞典一地区禽肉及禽类产品

  • 电影《消失的她》总票房破14亿
                _全球最资讯
    电影《消失的她》总票房破14亿 _全球最资讯

  • 红蜻蜓(603116.SH)2022年度权益分派:每股派0.35元 7月6日股权登记|全球热点
    红蜻蜓(603116.SH)2022年度权益分派:每股派0.35元 7月6日股权登记|全球热点

  • 热点在线丨国内首台无人智慧加油通航服务站在上海投放使用
    热点在线丨国内首台无人智慧加油通航服务站在上海投放使用

  • 盒马在郑开第4店 “豫制菜”发展迎新机
    盒马在郑开第4店 “豫制菜”发展迎新机

  • 【全球新视野】蒙犹以为犯军令不可以乡里故而废法遂垂涕斩之翻译_此言孙可以为王父尸 子不可以为父尸 翻译
    【全球新视野】蒙犹以为犯军令不可以乡里故而废法遂垂涕斩之翻译_此言孙可以为王父尸 子不可以为父尸 翻译

  • 全球观察:与年轻人完美契合 荣耀90系列销量大涨
    全球观察:与年轻人完美契合 荣耀90系列销量大涨

  • 中大力德:控股股东及其一致行动人拟合计减持不超2%公司股份
    中大力德:控股股东及其一致行动人拟合计减持不超2%公司股份

  • 灰指甲怎么防止传染_灰指甲会传染别人吗-环球要闻
    灰指甲怎么防止传染_灰指甲会传染别人吗-环球要闻

  • 万里扬:机器人减速器产品处于样机试制阶段
    万里扬:机器人减速器产品处于样机试制阶段

  • 英国王室伦敦地产贬值5亿英镑
    英国王室伦敦地产贬值5亿英镑

  • 中电联与华为数字能源技术有限公司签署战略合作协议
                _微速讯
    中电联与华为数字能源技术有限公司签署战略合作协议 _微速讯

  • 帝科股份:实控人之一拟减持公司不超2%股份
                 环球快看点
    帝科股份:实控人之一拟减持公司不超2%股份 环球快看点

  • 还敢喝无糖可乐么?世卫或在下月宣布:阿斯巴甜“可能致癌”! 世界新动态
    还敢喝无糖可乐么?世卫或在下月宣布:阿斯巴甜“可能致癌”! 世界新动态

  • 时讯:中国石油大学(华东)2023年广西理工(高校专项)招生计划
    时讯:中国石油大学(华东)2023年广西理工(高校专项)招生计划

  • 呼和浩特市土左旗市场监督管理局开展餐饮单位安全用气知识培训|世界视讯
    呼和浩特市土左旗市场监督管理局开展餐饮单位安全用气知识培训|世界视讯

  • 宇瞳光学:发行可转债募资不超6亿元申请获证监会同意注册批复-世界新动态
    宇瞳光学:发行可转债募资不超6亿元申请获证监会同意注册批复-世界新动态

  • 三大股指均缩量收星-当前信息
    三大股指均缩量收星-当前信息

  • 环球热点评!橙色山洪灾害气象预警:安徽西南部、湖北东部局地发生山洪灾害可能性大
    环球热点评!橙色山洪灾害气象预警:安徽西南部、湖北东部局地发生山洪灾害可能性大

  • 12家公司主动私有化退市 港股流动性问题求解!
    12家公司主动私有化退市 港股流动性问题求解!

  • 宝藏田野丨如何推进乡村振兴?这里有浙江答案
    宝藏田野丨如何推进乡村振兴?这里有浙江答案

  • 中国银行间交易商协会:鼓励多元化增信发债方式提升二级市场流动性
                 每日简讯
    中国银行间交易商协会:鼓励多元化增信发债方式提升二级市场流动性 每日简讯

  • 热讯:快可电子:拟2.4亿元投建光伏连接系统项目
    热讯:快可电子:拟2.4亿元投建光伏连接系统项目

  • 世界快资讯丨成都:到2025年满足60万辆以上电动汽车的充(换)电需求 累计建成充电站3200座
    世界快资讯丨成都:到2025年满足60万辆以上电动汽车的充(换)电需求 累计建成充电站3200座

  • 新资讯:圆通速递:拟使用3亿-5亿元回购公司股份
    新资讯:圆通速递:拟使用3亿-5亿元回购公司股份

  • 七月星空观赏指南:银河“纵观天穹”迎来绝佳观赏季
    七月星空观赏指南:银河“纵观天穹”迎来绝佳观赏季

  • 万顺新材:子公司签订首张复合铜箔产品订单
                |观点
    万顺新材:子公司签订首张复合铜箔产品订单 |观点

  • 腐漫画官网 腐漫画谢肉祭酒吧-天天微资讯
    腐漫画官网 腐漫画谢肉祭酒吧-天天微资讯

  • 姜广涛晒工作照片宣布“开工” 3个月前曾被吼浪工作室称其涉嫌刑事犯罪,永久终止合作关系 全球播资讯
    姜广涛晒工作照片宣布“开工” 3个月前曾被吼浪工作室称其涉嫌刑事犯罪,永久终止合作关系 全球播资讯

  • 央行二季度问卷调查:59.9%企业家认为宏观经济热度“正常”
    央行二季度问卷调查:59.9%企业家认为宏观经济热度“正常”

  • 国家统计局:2022年全国文化及相关产业营收超16万亿元
    国家统计局:2022年全国文化及相关产业营收超16万亿元

  • 今年夏天火了一种“气泡水”穿搭,清凉舒适又高级,明星也在跟风
    今年夏天火了一种“气泡水”穿搭,清凉舒适又高级,明星也在跟风

  • 虎皮红烧肉做法?
    虎皮红烧肉做法?

  • iQOO 11S搭配200W快充 充5分钟玩3小时
    iQOO 11S搭配200W快充 充5分钟玩3小时

  • 珍宝岛:子公司获得发明专利证书
                 每日视讯
    珍宝岛:子公司获得发明专利证书 每日视讯

  • 央行:第二季度房地产企业贷款需求指数为47.0% 比上季下降8.4个百分点
    央行:第二季度房地产企业贷款需求指数为47.0% 比上季下降8.4个百分点

  • 明天9点!最新一期《阳光问廉》重磅来袭!-天天观速讯
    明天9点!最新一期《阳光问廉》重磅来袭!-天天观速讯

  • 市场监管总局修订出台《禁止滥用知识产权排除、限制竞争行为规定》,8月1日起施行
    市场监管总局修订出台《禁止滥用知识产权排除、限制竞争行为规定》,8月1日起施行

  • 微头条丨房地产行业资金流出榜:万科A等5股净流出资金超3000万元
    微头条丨房地产行业资金流出榜:万科A等5股净流出资金超3000万元

  • 独家述评|暑假不是焦虑的季节
    独家述评|暑假不是焦虑的季节

  • 生态环境部:对自动监测数据作假行为“零容忍”
    生态环境部:对自动监测数据作假行为“零容忍”

  • 微信支付再度回应高校费率问题:本意是对费率实施更加精细化的优惠措施,但沟通中存在误解,对此深表歉意,即刻修正
                -世界快播报
    微信支付再度回应高校费率问题:本意是对费率实施更加精细化的优惠措施,但沟通中存在误解,对此深表歉意,即刻修正 -世界快播报

  • 北京市2022年老年抚养系数为51.1% 同比增长3.8%_全球速讯
    北京市2022年老年抚养系数为51.1% 同比增长3.8%_全球速讯

  • 环球简讯:多家高校下月起停用微信支付,微信团队致歉:即刻修正
    环球简讯:多家高校下月起停用微信支付,微信团队致歉:即刻修正

  • 【热闻】杨家将评书刘兰方_杨家将
    【热闻】杨家将评书刘兰方_杨家将

  • OpenAI首个海外分部官宣落户 科技公司为何扎堆跑向伦敦?
    OpenAI首个海外分部官宣落户 科技公司为何扎堆跑向伦敦?

  • 生态环境部:对自动监测数据作假行为“零容忍”
    生态环境部:对自动监测数据作假行为“零容忍”

  • 一路扬帆的中国工业企业晶惠迪:23年坚持只做高品质单色COG液晶屏
    一路扬帆的中国工业企业晶惠迪:23年坚持只做高品质单色COG液晶屏

  • 还珠格格44岁赵薇近照_因还珠格格成名
    还珠格格44岁赵薇近照_因还珠格格成名

  • 金价压力重重 千九关口能否守牢?-新视野
    金价压力重重 千九关口能否守牢?-新视野

  • 荔枝团体标准再添新势力 东莞发布国内首个冰荔荔枝产品标准
    荔枝团体标准再添新势力 东莞发布国内首个冰荔荔枝产品标准

  • 荣耀CEO赵明:即将发布折叠旗舰Magic V2 并计划将AI大模型引入终端
    荣耀CEO赵明:即将发布折叠旗舰Magic V2 并计划将AI大模型引入终端

  • 全球要闻:近6月净值涨幅最高达3.46%!理财公司“固收+期权”公募产品业绩排行榜出炉
    全球要闻:近6月净值涨幅最高达3.46%!理财公司“固收+期权”公募产品业绩排行榜出炉

  • 赚钱效应不佳 年内新发基金规模降逾两成-世界通讯
    赚钱效应不佳 年内新发基金规模降逾两成-世界通讯

  • 中国太保集团总裁傅帆:深入对大湾区网络安全及数字孪生等领域的研究
    中国太保集团总裁傅帆:深入对大湾区网络安全及数字孪生等领域的研究

  • 习近平对党的建设和组织工作作出重要指示 代表党中央向全国广大共产党员致以节日问候_当前独家
    习近平对党的建设和组织工作作出重要指示 代表党中央向全国广大共产党员致以节日问候_当前独家

  • 国家电投声明:有不法企业假冒集团所属子公司,已向有关部门报案、举报
    国家电投声明:有不法企业假冒集团所属子公司,已向有关部门报案、举报

  • 符文工房5盐烤鲑鱼怎么做
    符文工房5盐烤鲑鱼怎么做

  • 今日热闻!美国芯片出口若再收紧对中国业务影响几何?英伟达回应
    今日热闻!美国芯片出口若再收紧对中国业务影响几何?英伟达回应

  • 世界视讯!馨子演过的电视剧大全(馨子演过的电视剧)
    世界视讯!馨子演过的电视剧大全(馨子演过的电视剧)

  • 速递!5月经济增长主要由服务业驱动 未来全面复苏可期|中国观察
    速递!5月经济增长主要由服务业驱动 未来全面复苏可期|中国观察

  • 节假日安排调休怎么算工资_节假日安排
    节假日安排调休怎么算工资_节假日安排

  • 房贷延期后再断供会怎么样?房贷延期后还能二次逾期吗? 天天百事通
    房贷延期后再断供会怎么样?房贷延期后还能二次逾期吗? 天天百事通

  • 安永:上半年A股IPO活动全球领先 港股下半年有望逐步复苏 天天微速讯
    安永:上半年A股IPO活动全球领先 港股下半年有望逐步复苏 天天微速讯

  • 《漫威蜘蛛侠2》成最令人印象深刻游戏画面之一
    《漫威蜘蛛侠2》成最令人印象深刻游戏画面之一

  • 国画马的画法步骤 入门_马的最简单画法|快讯
    国画马的画法步骤 入门_马的最简单画法|快讯

  • 李家超:对香港经济全面复苏谨慎乐观 海外资金和投资正回港
    李家超:对香港经济全面复苏谨慎乐观 海外资金和投资正回港

  • 每日热点:如果反复试自提柜的取件码 能否打开柜门?
    每日热点:如果反复试自提柜的取件码 能否打开柜门?

  • 酒店餐饮板块震荡走低,锦江酒店跌超3%
                -新动态
    酒店餐饮板块震荡走低,锦江酒店跌超3% -新动态

  • 关于猫咪的文艺唯美句子(关于猫咪的文艺唯美句子 有哪些) 世界独家
    关于猫咪的文艺唯美句子(关于猫咪的文艺唯美句子 有哪些) 世界独家

  • 苹果MR板块午后震荡走高 立讯精密大涨7%
    苹果MR板块午后震荡走高 立讯精密大涨7%

  • 生物医药港股走势分歧 云顶新耀涨16%
    生物医药港股走势分歧 云顶新耀涨16%

  • 国家发改委产业司专题研究制造业智能化发展
                 全球看热讯
    国家发改委产业司专题研究制造业智能化发展 全球看热讯

  • 通业科技(300960):该股换手率大于8%(06-29)|聚看点
    通业科技(300960):该股换手率大于8%(06-29)|聚看点

  • 北向资金净卖出超60亿元
    北向资金净卖出超60亿元

  • 室外监控摄像头品牌排行榜前十名_室外监控摄像头怎么选
    室外监控摄像头品牌排行榜前十名_室外监控摄像头怎么选

  • 无锡海东共奏“协作曲”:带动民众就近就业增收
    无锡海东共奏“协作曲”:带动民众就近就业增收

  • 实时:青山美食推荐:肉末茄子粉丝煲,白菜豆腐锅,红烧鸡块……的做法
    实时:青山美食推荐:肉末茄子粉丝煲,白菜豆腐锅,红烧鸡块……的做法

  • 快讯:英伟达 RTX 4060 显卡解禁评测:性能提升约 22%
    快讯:英伟达 RTX 4060 显卡解禁评测:性能提升约 22%

  • 世界人工智能大会将展示30多款大模型
    世界人工智能大会将展示30多款大模型

  • 广东拟推“医保信用积分”,个人信用A级享就医便利
    广东拟推“医保信用积分”,个人信用A级享就医便利

  • 盐城供电:推进新型电力系统综合示范区创先优秀项目建设 精选
    盐城供电:推进新型电力系统综合示范区创先优秀项目建设 精选

  • 消费电子板块冲高
                 环球资讯
    消费电子板块冲高 环球资讯

  • 城乡公交二十年 沿途乡村看发展|当前热点
    城乡公交二十年 沿途乡村看发展|当前热点

  • CPO概念股集体反弹 联特科技涨超10%
                -焦点观察
    CPO概念股集体反弹 联特科技涨超10% -焦点观察

  • 每日热闻!国产软件板块午后异动拉升 中兴通讯涨超6%
    每日热闻!国产软件板块午后异动拉升 中兴通讯涨超6%

  • 暑假未成年人只能周五六日打游戏
    暑假未成年人只能周五六日打游戏

  • 世界今热点:安永报告:上半年A股IPO 173家保持高位,筹资2104亿元同比下降33%
    世界今热点:安永报告:上半年A股IPO 173家保持高位,筹资2104亿元同比下降33%

  • 【阿卡迪亚茶话会】暑假到来 分享你的夏日度假计划(回帖有奖)
    【阿卡迪亚茶话会】暑假到来 分享你的夏日度假计划(回帖有奖)

  • 荣耀赵明:大家联合起来,打破苹果一家独大! 全球观速讯
    荣耀赵明:大家联合起来,打破苹果一家独大! 全球观速讯

  • 生态环境部:积极稳妥开展长江流域水生态考核试点
    生态环境部:积极稳妥开展长江流域水生态考核试点

  • “一键办理”!苏州居民充电桩报装更方便啦!-环球快报
    “一键办理”!苏州居民充电桩报装更方便啦!-环球快报

  • 全球速读:小办公室办公桌摆放_办公室办公桌摆放方向
    全球速读:小办公室办公桌摆放_办公室办公桌摆放方向

  • 住建部部长倪虹:研究建立房屋体检、养老、保险三项制度
    住建部部长倪虹:研究建立房屋体检、养老、保险三项制度

  • 全球热点!南方精工收关注函:要求说明“相关样品已送至美国特斯拉,试验结果良好,获得较高认可”的依据
    全球热点!南方精工收关注函:要求说明“相关样品已送至美国特斯拉,试验结果良好,获得较高认可”的依据

  • Doinb实名曝光RNG卡合同,直言小明想离开,却被卡着没办法走
    Doinb实名曝光RNG卡合同,直言小明想离开,却被卡着没办法走

  • 杭州高中历年录取分数线汇总(学校+年份+分数)-世界聚看点
    杭州高中历年录取分数线汇总(学校+年份+分数)-世界聚看点

  • 隆基绿能:二季度公司硅片和组件出货量环比不断增加
                 环球新动态
    隆基绿能:二季度公司硅片和组件出货量环比不断增加 环球新动态

  • 动态焦点:组件尺寸标准尚未达成一致性意见 预计将进行第三轮协商讨论
    动态焦点:组件尺寸标准尚未达成一致性意见 预计将进行第三轮协商讨论

  • 隆扬电子:6月28日融资净买入118.81万元,连续3日累计净买入576.12万元
    隆扬电子:6月28日融资净买入118.81万元,连续3日累计净买入576.12万元

  • 海南自由贸易港集中开工项目180个 总投资额366亿元 焦点速讯
    海南自由贸易港集中开工项目180个 总投资额366亿元 焦点速讯

  • 美拟扩大对华芯片限制,英伟达首席财务官:将令美产业永久丧失机会
    美拟扩大对华芯片限制,英伟达首席财务官:将令美产业永久丧失机会

  • 环球观热点:测试适合自己学的专业_测试适合自己的纹身
    环球观热点:测试适合自己学的专业_测试适合自己的纹身

  • 【环球新视野】小书上买基金靠谱吗?探讨其风险和收益!
    【环球新视野】小书上买基金靠谱吗?探讨其风险和收益!

  • 中国软件国际是华为盘古大模型重要交付伙伴 世界今头条
    中国软件国际是华为盘古大模型重要交付伙伴 世界今头条

  • 即时焦点:2023版3克熊猫金币价格(2023年06月29日)
    即时焦点:2023版3克熊猫金币价格(2023年06月29日)

  • 环球热讯:2023年兔年金银币价格表(2023年06月29日)
    环球热讯:2023年兔年金银币价格表(2023年06月29日)

  • 【光明时评】让乡村工匠更好发光发热 全球热消息
    【光明时评】让乡村工匠更好发光发热 全球热消息

  • 光伏板块持续走高,金博股份涨近8%,光伏50ETF(516880)6月8日来累计反弹近10%丨ETF观察
    光伏板块持续走高,金博股份涨近8%,光伏50ETF(516880)6月8日来累计反弹近10%丨ETF观察

  • 当前动态:网传高考677分的学霸作息表,有人看过表示很佩服,有人直呼:窒息得要死!
    当前动态:网传高考677分的学霸作息表,有人看过表示很佩服,有人直呼:窒息得要死!

  • 贵州茅台:2022年度经营活动产生的现金流量净额减少有两个主要原因
                 世界观点
    贵州茅台:2022年度经营活动产生的现金流量净额减少有两个主要原因 世界观点

  • 航空运输板块震荡下挫
    航空运输板块震荡下挫

  • 全球快消息!甘肃350亿氢能项目招标方并非国家电投旗下公司
    全球快消息!甘肃350亿氢能项目招标方并非国家电投旗下公司

  • 环球看点!佛山三水新城挂牌一宗6.8万平米商住地 投资总额不低于9.8亿元
    环球看点!佛山三水新城挂牌一宗6.8万平米商住地 投资总额不低于9.8亿元

  • 【环球报资讯】「图说」拦
    【环球报资讯】「图说」拦