记录在代码审计过程中,学习到的知识 估计内容会比较乱,也不知道怎么分类,就记录给自己看吧
传参
一、springMVC
springMVC获取请求参数:https://www.cnblogs.com/taozhiyaoyao99/p/15151811.html
@RequestMapping 注解的作用就是将请求地址url和处理请求的控制器方法关联起来,建立映射关系。 位置:写在类,或方法上。 value属性:是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址url 所对应的请求。 method属性:是一个RequestMethod类型的数组,表示该请求映射能够匹配 多种请求方式的请求 。 params属性:是一个字符串类型的数组,可以通过四种表达式设置请求参数 和请求映射的匹配关系。 “param”:要求请求映射所匹配的请求必须携带param请求参数。举例:username “!param”:要求请求映射所匹配的请求必须不能携带param请求参数。 “param=value”:要求请求映射所匹配的请求必须携带param请求参数且param=value。 “param!=value”:要求请求映射所匹配的请求必须携带param请求参数但是param!=value。举例:password!=123456 headers属性:通过请求的请求头信息匹配请求映射,也有以上四种方式。举例:headers={“host=localhost:8080”}
注意:对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解@GetMapping、@PostMapping、@PutMapping、@DeleteMapping 可以直接使用以上注解代替method参数!
1.1 获取请求参数
1、通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象。 2、通过控制器方法的形参获取请求参数 在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在 DispatcherServlet中就会将请求参数赋值给相应的形参。 3、@RequestParam
https://blog.csdn.net/sswqzx/article/details/84195043
url 将请求参数和控制器方法的形参创建映射关系 三个属性: value:指定为形参赋值的请求参数的参数名 required:是否必须传输此请求参数,默认值为true defaultValue:不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值 为""时,则使用默认值为形参赋值 也可以接收对象类型
https://www.cnblogs.com/blackblack/p/13904187.html
int addPeople(@RequestParam People people) {}
4、@RequestHeader 将请求头信息和控制器方法的形参创建映射关系 三个属性:value、required、defaultValue,用法同上 5、@CookieValue 将cookie数据和控制器方法的形参创建映射关系 三个属性:value、required、defaultValue,用法同上
6、通过POJO获取请求参数 可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值
二、@requestBody
内容基于Spring boot
@RequestBody的使用:https://blog.csdn.net/justry_deng/article/details/80972817/
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的); 一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。
get无请求体,使用请求体传参的是POST请求,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。
在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
注: 如果后端参数是一个对象,且该参数前是以@RequestBody修饰的,那么前端传递json参数时,必须满足以下要求:
后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,
会根据json字符串中的key来匹配对应实体类的属性,
如果匹配一致且json中的该key对应的值符合(或可转换为)
实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。
json字符串中,如果value为""的话,后端对应属性如果是String类型的,那么接受到的就是"",
如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null。
json字符串中,如果value为null的话,后端对应收到的就是null。
如果某个参数没有value的话,在传json字符串给后端时,要么干脆就不把该字段写到json字符串中;
要么写value时, 必须有值,null 或""都行。
示例: 1、@RequestBody直接以String接收前端传过来的json数据: 后端对应的Controller:
测试 2、@RequestBody以简单对象接收前端传过来的json数据: 后端对应的Controller: 测试 还有好些个例子,看原文吧
三、@para
为什么要用@para @para注解的用法解析:https://blog.csdn.net/qq_21040559/article/details/109105301
@Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解, 用于传递参数,从而可以与SQL中的的字段名相对应, 一般在2=<参数数量<=5时使用最佳
public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);
用法一、XML形式 用法二、注解形式
VO,DTO,PO对象
代码审计过程中,会发现有很多名称相似的类,如xxxVO,xxxDTO,xxxPO,然后他们之间又转来转去的,给人绕晕
https://blog.csdn.net/WB1224678/article/details/88891014
VO 是Value Object 的缩写,值对象,位于视图层,每一个字段与视图层所需要的字段对应。
DTO是Data Transfer Object 的缩写,数据传输对象,在视图层和服务层之间传输用来转换从PO到VO,或者从VO到PO的中间对象。
PO 是Persistent Object 的缩写,持久化对象,位于持久层,每一个字段,与数据库相对应。
对象转换
MapStruct优雅的转换bean对象:https://blog.csdn.net/czx2018/article/details/114696724
将业务相关的各种PO,VO,DTO对象互相转换,比较常用的工具类就是 BeanUtil ,但是BeanUtil有两个问题:1、底层使用了反射,效率不高。2、无法自定义转换规则,例如其中一个bean中的datetime是Date类型,而另一个bean中的datetime是String类型,这就无法转换过去了。 推荐bean转换工具:MapStruct
1、引入依赖 2、准备实体类
@Data
public class DogVO {
private int id;
private String name;
private int weight;
private Date birthday;}
@Data
public class DogPO {
private int id;
private String name;
private int weight;
private Date birthday;}
3、编写 DogConvertor 接口
@Mapper
public interface DogConvertor {
DogConvertor INSTANCE = Mappers.getMapper(DogConvertor.class);
DogPO voToPO(DogVO vo);
}
4、测试
public static void main(String[] args) {
DogVO dogVO = new DogVO();
dogVO.setId(1);
dogVO.setName("旺财");
dogVO.setWeight(20);
dogVO.setBirthday(new Date());
DogPO dogPO = DogConvertor.INSTANCE.voToPO(dogVO);
System.out.println(dogPO);
}
其他操作:
1、属性名不同的转换
@Mapping(source = "name", target = "dogName")
DogPO voToPO(DogVO vo);
2、属性类型不同的转换
@Mappings({
@Mapping(source = "name", target = "dogName"),
@Mapping(target = "birthday", expression = "java(cn.hutool.core.date.DateUtil.format(vo.getBirthday(), \"yyyy-MM-dd HH:mm:ss\"))")
})
DogPO voToPO(DogVO vo);
3、多个bean合为一个bean 新建TailVO,有狗狗尾巴属性,同时DogPO里也增添这个属性
@Data
@AllArgsConstructor
public class TailVO {
private int length;
}
@Mappings({
@Mapping(source = "vo.name", target = "dogName"),
@Mapping(target = "birthday", expression = "java(cn.hutool.core.date.DateUtil.format(vo.getBirthday(), \"yyyy-MM-dd HH:mm:ss\"))"),
@Mapping(source = "tailVO.length", target = "tailLength")
})
DogPO voToPO(DogVO vo, TailVO tailVO);
加密
密码加密 bcrypt模块的基本使用:https://www.it610.com/article/1304594116109176832.htm
看代码时不懂,以为bcrypt.genSalt(10)里的10数值是个固定的盐还是啥的,看着有点简单觉得好像有风险,搜搜才知道,10代表了复杂度
Lambda表达式
https://blog.csdn.net/qq_37465368/article/details/82908646 http://blog.oneapm.com/apm-tech/226.html
一种匿名函数 (对 Java 而言这并不完全正确,但现在姑且这么认为) 没有声明的方法,也即没有访问修饰符、返回值声明和名字。 方法只使用一次,而且定义很简短,就不必在类中费力写声明与方法了。
Java 中的 Lambda 表达式通常使用 (argument) -> (body) 语法书写,例如:
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
以下是一些 Lambda 表达式的例子:
(int a, int b) -> { return a + b; }
() -> System.out.println("Hello World");
(String s) -> { System.out.println(s); }
() -> 42
() -> { return 3.1415 };
assert断言
https://www.jianshu.com/p/3f2be2af12a4
unit.framework包下的Assert提供了多个断言方法.。 主用于比较测试传递进去的两个参数 。
使用比较简单,主要有以下函数: 1、Assert.assertEquals([String message],T expected,T actual) 比较两个参数是否相等, message是可选的消息,假如加入了该参数,则发生错误时会报告该消息。
2、Assert.assertNotEquals([String message],T expected,T actual) 比较两个参数是否不相等。
3、Assert.assertSame([String message],T expected,T actual) 以expected==actual运算的结果来判断。
expected.equals(actual) 和 expected==actual 的差别在于。
如果expected没有重写java.lang.Object的equals方法,那么就是两个java对象的内存地址比较,比较结果和 expected==actual的结果相同。
如果expected重写了equals方法(比如GregorianCalendar,BigDecimal类),那么比较的结果不一定和expected==actual的结果相同。
4、Assert.assertNotSame([String message],T expected,T actual) 以expected != actual运算的结果来判断。
5、Assert.assertTrue([String message],boolean condition) 如果表达式condition结果为真,则测试通过,message为可选信息,若有则condition结果为假时显示message的内容
6、Assert.assertFalse([String message],boolean condition) 如果表达式condition结果为假,则测试通过
7、Assert.assertArrayEquals([String message], Object[] expected, Object[] actual) 以最直接的方式比较数组:如果数组长度相同,且每个对应的元素相同,则两个数组相等,否则不相等。
8、Assert.assertNotNull([String message], Object object) 断言object为空
9、Assert.assertNotNull([String message], Object object) 断言object不为空
10、Assert.assertThat([String reason],T actual, Matcher matcher) 其中actual为需要测试的变量,matcher为使用Hamcrest的匹配符来表达变量actual期望值的声明; assertThat是Junit 4.4加入的新方法,理论上讲程序员可以只使用 assertThat 一个断言语句,结合 Hamcrest 提供的匹配符,就可以表达全部的测试思想。
cors跨域
cors漏洞简介:https://blog.csdn.net/qq_35569814/article/details/101068142
源码里显示,响应包Access-Control-Allow-Origin的值为请求包内origin字段的值。
httpResponse.setHeader("Access-Control-Allow-Origin", origin);
该漏洞同时需要Access-Control-Allow-Credentials 值为true,默认为true。
|