发表于: 2019-12-24 20:42:51

2 1120


啥也不说就是干!!!

今天完成的事情:

关于任务二的深度思考

1、什么叫MVC,Spring里对应的MVC分别是什么,是怎么收到用户请求然后分发给不同的Controller的?

之前日报有介绍,略过

2、什么是参数校验,前端和后端需要分别做校验吗?Validation的好处和坏处分别是什么,在真实项目中需要使用Validation吗?

前后端都需要参数校验(https://www.cnblogs.com/mr-yang-localhost/p/7812038.html

前端校验为了保证用户提交的数据符合规范,后端校验是为了保证当用户绕过前端请求时对提交的参数进行格式校验,过滤恶意请求,保证后端程序稳定性。

后端校验一般使用 Spinrg Validation 或者 Hibernate Validate

Hibernate Validator 基于 javax Validation 是对 JSR303 校验规范的实现

Spring Validation 实现规范是 Spring's JSR-303 ,是 标准 JSR-303 的一个变种


@Validated(Spring Validation 提供) 与 @Valid(标准 JSR-303提供)的区别

1、分组

@Validated:提供了分组功能,可以在入参校验时,根据不同的分组采用不同的校验机制

@Valid 没有提供分组校验的功能

分组顺序校验时,按照指定的分组先后顺序进行验证,前面的验证不通过,后面的分组就不进行校验

使用场景:新增用户信息的时候,不需要验证 userId(系统分配生成);修改用户信息时候需要验证 userId,这个时候就可以使用 @Validated 的分组功能来实现

public class Student {

   @NotBlank
   @Range(min 1max = Integer.MAX_VALUEmessage "必须大于0"groups = {GroupA.class})
   /**用户id*/
   private int id;

   @NotBlank(message "用户名不能为空")
   @Length(min 4max 20message "必须在[4,20]"groups = {GroupB.class})
   private String name;
   @NotBlank(message "学号不能为空")
   @Range(min 0max 100message "学号必须在[0,100]"groups = {Default.class})
   private String onlineNum;

}

如上 Person 所示,3个分组分别校验字段如下:

GroupA 校验字段 userId

GroupB验证字段userName、sex;

Default验证字段age(Default是Validator自带的默认分组)

GroupA、GroupB、Default 验证不通过抛出 BindException 

@RequestMapping(value "/",method = RequestMethod.POST)
@ResponseBody
public Result<Integer> addStudentInfo@Validated({Student.GroupA.class, Student.GroupB.class}) Student student){
int id = studentService.addStudent(student);
   String msg = "";
   if(id>0){
      msg="插入成功";
   }
   else{
      msg="插入失败";
   }
   return Result.success(id,msg);
}

此外还可以指定组序列

@GroupSequence({GroupA.class, GroupB.class, Default.class})
public interface GroupOrder {
}

public Result<Integer> addStudentInfo@Validated({GroupOrder.class}) Student student) {

}


2、注解修饰的地方

@Validated 可以用在类型、方法和方法参数上。但不能用在成员属性(字段)上

@Valid 可以用在方法、构造函数、方法参数和成员属性(字段)上


两者的是否能用在成员属性(字段)上直接影响到是否提供嵌套校验的功能


3、嵌套校验

先说明一下什么是嵌套校验。比如现在有个实体 Item:

public class Item {

   @NotNull(message = "id不能为空")
   @Min(value = 1, message = "id必须为正整数")
   private Long id;

   @NotNull(message = "props不能为空")
   @Size(min = 1, message = "至少要有一个属性")
   private List<Prop> props;
}

Prop 带有很多属性,并且其中也有自己的校验机制

public class Prop {

   @NotNull(message = "pid不能为空")
   @Min(value = 1, message = "pid必须为正整数")
   private Long pid;

   @NotNull(message = "vid不能为空")
   @Min(value = 1, message = "vid必须为正整数")
   private Long vid;

   @NotBlank(message = "pidName不能为空")
   private String pidName;

   @NotBlank(message = "vidName不能为空")
   private String vidName;
}


现在有 ItemController 接收 Item 类型的入参

@RestController
public class ItemController {
   @RequestMapping("/item/add")
   public void addItem(@Validated Item item, BindingResult bindingResult) {
       doSomething();
   }
}

以上的代码,如果 Item 实体中的 props 属性不额外加注解,只有 @NotNull 和 @Size,无论入参采用 @Validated 还是 @Valid 验证,Spring Validation 框架只会对 Item 的 id 和 props 做非空和数量验证,不会对 props 实体内的字段进行校验,也就是说 @Validate 和 @Valid 加在方法参数前,都不会自动对参数进行嵌套校验。如果 List<Prop> 中有 Prop 的 pid 为空或者负数,入参校验是不能检测出来的。

要实现嵌套校验,必须在 Item 实体的 props 字段上明确指出该实体内的字段也要进行校验。由于 @Validated 不能修饰成员属性(字段)上,所以这里需要用 @Valid 

public class Item {
   @NotNull(message = "id不能为空")
   @Min(value = 1, message = "id必须为正整数")
   private Long id;

   @Valid // 嵌套验证必须用@Valid
   @NotNull(message = "props不能为空")
   @Size(min = 1, message = "props至少要有一个自定义属性")
   private List<Prop> props;
}


SpringMvc Controller 中参数校验:SpringMVC 通常客户端传入的参数有三种

1)校验 RequestBody 

RequestBody:当客户端提交的 Body 为 Json 时候,通常 @RequestBody 会将 Json 映射到入参的Java对象上

那么可以在入参 Java 对象前加上 @Valid 告诉 Spring 要对该入参的字段进行校验,如果校验失败会抛出 MethodArgumentNotValidException。(如果没有使用 @RequestBody,表单数据到 Pojo 的映射,校验失败则抛出 BindException)

2) 校验 @PathVariable 和 @RequestParam 参数

一般都是属于方法级别的参数验证,因为路径变量和请求参数的基本类型。此时直接在 Controller 方法参数上加约束。注意:使用@Valid注解,对RequestParam对应的参数进行注解,是无效的,需要使用@Validated注解来使得验证生效。如下所示:

@Controller
@RequestMapping("student")
@Validated
public class StudentController2 {

   @Resource
   StudentService studentService;

   @RequestMapping(value = "/{id}/{name}", method = RequestMethod.GET)
   @ResponseBody
   public Student getStudentInfo(@PathVariable Integer id, @PathVariable @Size(min = 1, max = 3, message = "名字长度为1-3") String name) {
       Student student = new Student();
       student.setName(name);
       student.setId(id);
       return student;
   }

}

并且在 Controller 类级别加上 @Validated (当 @Validated 用于方法级别时候是为了实现 validation group)。如果参数校验失败后会抛出 ConstraintViolationException 异常(但是 Spring 没有提供默认的该异常处理器,会转化为 500-Internal Server Error),如果想要将其转化为 400 则在全局异常处理器中定义该异常的处理。

此外还需要使用 MethodValidationPostProcessor 的 Bean

<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
   <property name="validator" ref="validator"/>
</bean>

3、SpringMVC分页查询和显示

之前日志已经实现了分页查询,略过

4、“内网IP+端口”和“外网IP+端口”和"域名"三种方式方式的差别是什么?什么时候用内网?什么时候用外网IP,什么时候用域名访问?  (参考师兄日志)

内网IP+端口是本地网络内部局域网的各个服务,不连通外网
外网IP+端口是公网上的IP指向的地址里的服务,可以在任何连通网络的地方访问
域名是IP的一层外衣,只是为了方便识别IP地址。

内网因为范围小,速度快,而且安全性高,所以一般公司在不需要外部网络或者需要高度安全环境、需要保密的环境的时候使用。

5、内网IP和外网IP的区别是什么,在服务器上测试接口是否被防火墙屏蔽的时候,该用内网IP检测,还是该用外网IP检测?

内网的ip大多通过路由器或者局域网分配,外网ip由运营商分配
外网IP是全世界唯一的IP地址,仅分配给一个网络设备

内网IP是由路由器分配给每一部内部使用的IP地址,而内网的所有用户都是通过同一个外网IP地址进行上网的,而内网的IP地址每个人的都不一样,Internet上的用户也无法直接访问到内网用户

6、在Linux服务器上,有哪些工具是可以测试接口的,怎么用Wget或者是Curl分别发送Rest的四种请求?

明天具体学习

7、PostMan是什么,为什么要使用他来测试接口,除了Postman,还有哪些工具可以测试?

Postman 测试接口数据,作为客户端模拟浏览器调用接口

其余的类似工具还有:RESTClient、jmeter、loadrunner

8、该怎么模拟假数据,为什么在真实项目中,我们通常都是先定义接口,再写假数据,再去写业务逻辑?

前后端分离的项目当中,后端开发是不需要依赖前端的,但是前端的动态页面是依赖后端提供的数据的,如果前端脱离后端自己定义数据结构时,与真实数据调试时难免造成不必要的改动而浪费开发时间,所以在真实开据。发环境中,需要前后端定义接口后,后端提供假数即数据结构,因为这是和DB设计时相关的,当然,如果前后端约定好数据结构,返回类型,前端也可以自己mock数据

9、对Service返回的结果是否要打日志,应该打什么样的日志,为什么?

 明天重点学习

10、对Service返回的结果是否要判空,为什么?

如果是往前端页面传输数据是要判断是否为空

11、在Controller里应该怎么处理Service的异常,大段的Try Catch 会有什么坏处?

大段的Try Catch 会有什么坏处
1.try catch的代价比较大。相对于判断返回值,抛出异常到捕获,需要更多的代码,程序不易阅读
2.Java的异常机制是由JVM控制的,业务逻辑复杂的情况下,会影响controller的执行效率
解决方法:
1.用错误码控制业务流程,需要对每个接口的返回都要做一个错误码的校验

2.自定义异常处理类,使用springMVC提供的统一的异常处理方式

12、怎么查看Nginx的访问请求时间,多少的响应时间是合理的,并发1000和单线程访问的差别是什么,Nginx可以支持多少并发,Tomcat可以支持多少并发,为什么要在Tomcat之前配置一个Nginx?

明天重点学习

13、域名和端口号是怎么对应起来的?应该通过域名访问吗,从域名服务商到服务器的流程是怎么样的?

一个域名可以绑定 ip+端口号,当通过域名访问服务器时候,先找本地的 Host 文件中是否配置了域名与 IP 的映射,如果没有会通过 DNS 找到 域名对应的 IP 地址,然后访问到对应部署的服务

14、端口是什么含义,怎么判断一个端口是否被占用了,如何判断一个端口是否被防火墙拦截,怎么用Telnet判断端口号是否打开?

明天重点学习

15、WEB服务器通常要配置哪几个端口,如果一台服务器上有多个不同的WEB服务,该怎么规划端口的使用,修真院的端口分配是怎么样的?

web 服务器一般要开放 80(http)、443(https)、3306(mysql)、22 (ssh) 21(ftp)端口。一般一台服务器只部署一个 WEB 服务。这样单台服务器挂掉不会影响其他服务

16、常用的性能统计命令有哪些,Top,Vmstat,free等命令都有什么用处,CPU占用率,内存使用分别代表什么含义?到什么情况下,应该产生报警信息?

明天重点学习

17、为什么要知道响应时间的分布情况,如果一个请求很慢,它的时间可能会被耗费在哪里? 

响应时间的分布情况可以及时的获悉异常,或者获取到其它重要信息。

请求耗时一般是几个地方:

1.网络波动;

2.服务器db连接过多;

3.服务器负载过高;

4.资源加载处理;

18、怎么查看Resin或者是Tomcat中的DB访问时间和Controller时间,有没有可能用Aop的方法自动记录Controller的时间和DB时间?Controller时间和DB时间的区别是什么,在你写的业务逻辑里,相差有多大? 

明天重点学习

19、怎么判断WEB容器是否收到了一个Http请求,WEB容器中的Access.log是什么意思,包含哪些字段,代表什么含义,是哪里配置修改字段的。

之前日志有略过

20、为什么通常都是将部署文件放置在/data/盘下,在云服务器中数据盘和系统盘的区别是什么?

第一部署文件集中在一起比较容易管理,第二data一般都是部署网站的根目录

数据盘和系统盘就像是win的d盘和c盘,一般数据都不推荐放在系统盘

21、常用的主流数据库有哪些,Mysql有几种安装方式? 

1.关系型数据库:
SQLITE ,Sybase,DB2,ORACLE,MYSQL,SQLSERVER,Access
2.非关系型数据库
Redis,Hbase,MongodDB,Neo4j 
一种特殊的文件存放 HDF5
非传统的关系型数据库KDB+
3.Mysql有几种安装方式?  

Yum安装Mysql,rpm安装Mysql ,二进制安装

22、有哪些常用的云服务器公司,Linux服务器和Windows服务器的差别是什么,Linux有哪些主流的版本,不同版本之间的差别在哪里?  

国内:阿里云、腾讯云、百度云、华为云等等
国外:亚马逊,微软
两种不同的系统的服务器生态不一样,windows图形化比较好,linux比较稳定,windows操作性比较好,Linux安全好

Linux 主要有RedHat、CentOS、Debian 、 Fedora 、SUSE家族

23、什么是ssh?如何在linux服务器上从网站下载文件?

SecureShell的缩写,通过使用SSH,可以把所有传输的数据进行加密。可以通过命令用ssh登录服务器,

wget http://xxx.xxx.x.xxxx.tar.gz 而且linux也有自己的维护社区,也可以使用yum来进行安装,比如yum install xxx

24、C标签是什么,为什么要使用C标签,有哪些常见的指令?

STL 核心标签库(C标签)

JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言。

这里写图片描述

明天计划的事情:

1、AOP 记录 Service 日志

2、Ngnix 学习

3、Linux 中 curl 接口测试及端口、性能监控相关命令学习

4、深度思考的其他内容

遇到的问题:

1、关于 Controller 方法入参的校验(已解决)

2、@Validated 不生效,需要在 SpringMVC.xml 文件中配置

MethodValidationPostProcessor

收获:

重点学习了关于Spring 数据校验的各种情况


返回列表 返回列表
评论

    分享到