2021-09-03

##一,作为架构人员,和其他同学编写gateway网关微服务
packagecom.kkb.kkbgateway.authorization;
importcn.hutool.core.convert.Convert;
importcn.hutool.core.util.StrUtil;
importcn.hutool.json.JSONUtil;
importcom.kkb.kkbcommon.constant.AuthConstant;
importcom.kkb.kkbcommon.domain.UserDto;
importcom.kkb.kkbgateway.config.IgnoreUrlsConfig;
importcom.nimbusds.jose.JWSObject;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.http.HttpMethod;
importorg.springframework.http.server.reactive.ServerHttpRequest;
importorg.springframework.security.authorization.AuthorizationDecision;
importorg.springframework.security.authorization.ReactiveAuthorizationManager;
importorg.springframework.security.core.Authentication;
importorg.springframework.security.core.GrantedAuthority;
importorg.springframework.security.web.server.authorization.AuthorizationContext;
importorg.springframework.stereotype.Component;
importorg.springframework.util.AntPathMatcher;
importorg.springframework.util.PathMatcher;
importreactor.core.publisher.Mono;
importjava.net.URI;
importjava.text.ParseException;
importjava.util.ArrayList;
importjava.util.Iterator;
importjava.util.List;
importjava.util.Map;
importjava.util.stream.Collectors;
/**
*鉴权管理器,用于判断是否有资源的访问权限
/
@Component
publicclassAuthorizationManagerimplements
ReactiveAuthorizationManager{
@Autowired
privateRedisTemplate<String,Object>redisTemplate;
@Autowired
privateIgnoreUrlsConfigignoreUrlsConfig;
@Override
publicMonocheck(Monomono,
AuthorizationContextauthorizationContext){
ServerHttpRequestrequest=authorizationContext.getExchange().getRequest();
URIuri=request.getURI();
PathMatcherpathMatcher=newAntPathMatcher();
//白名单路径直接放行
ListignoreUrls=ignoreUrlsConfig.getUrls();
for(StringignoreUrl:ignoreUrls){
if(pathMatcher.match(ignoreUrl,uri.getPath())){
returnMono.just(newAuthorizationDecision(true));
}
}
//对应跨域的预检请求直接放行
if(request.getMethod()==HttpMethod.OPTIONS){
returnMono.just(newAuthorizationDecision(true));
}
//不同用户体系登录不允许互相访问
try{
Stringtoken=request.getHeaders().getFirst(AuthConstant.JWT_TOKEN_HEADER);
if(StrUtil.isEmpty(token)){
returnMono.just(newAuthorizationDecision(false));
}
StringrealToken=token.replace(AuthConstant.JWT_TOKEN_PREFIX,"");
JWSObjectjwsObject=JWSObject.parse(realToken);
StringuserStr=jwsObject.getPayload().toString();
UserDtouserDto=JSONUtil.toBean(userStr,UserDto.class);
if(AuthConstant.ADMIN_CLIENT_ID.equals(userDto.getClientId())
&&!pathMatcher.match(AuthConstant.ADMIN_URL_PATTERN,uri.getPath())){
returnMono.just(newAuthorizationDecision(false));
}
if(AuthConstant.PORTAL_CLIENT_ID.equals(userDto.getClientId())&&
pathMatcher.match(AuthConstant.ADMIN_URL_PATTERN,uri.getPath())){
returnMono.just(newAuthorizationDecision(false));
}
}catch(ParseExceptione){
e.printStackTrace();
returnMono.just(newAuthorizationDecision(false));
}
//非管理端路径直接放行
if(!pathMatcher.match(AuthConstant.ADMIN_URL_PATTERN,uri.getPath())){
returnMono.just(newAuthorizationDecision(true));
}
//管理端路径需校验权限
Map<Object,Object>resourceRolesMap=
redisTemplate.opsForHash().entries(AuthConstant.RESOURCE_ROLES_MAP_KEY);
Iteratoriterator=resourceRolesMap.keySet().iterator();
Listauthorities=newArrayList<>();
while(iterator.hasNext()){
Stringpattern=(String)iterator.next();
if(pathMatcher.match(pattern,uri.getPath())){
authorities.addAll(Convert.toList(String.class,
resourceRolesMap.get(pattern)));
}
}
authorities=authorities.stream().map(i->i=AuthConstant.AUTHORITY_PREFIX+
i).collect(Collectors.toList());
//认证通过且角色匹配的用户可访问当前路径
returnmono
.filter(Authentication::isAuthenticated)
.flatMapIterable(Authentication::getAuthorities)
.map(GrantedAuthority::getAuthority)
.any(authorities::contains)
.map(AuthorizationDecision::new)
.defaultIfEmpty(newAuthorizationDecision(false));
}
}
在这里学习了很多网关相关的知识,通过fegin调用其他微服务
##二,在Apifox中编写接口
![在这里插入图片描
述](https://img-blog.csdnimg.cn/2eee2f2975ea488aa4955fa8f19c1178.png?x-oss-process=image
/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAd2VpeGluXzQ1NjY0M
jAw,size_20,color_FFFFFF,t_70,g_se,x_16)
##三,编写代码
packagecom.kkb.kkbportal.controller;
importcom.github.pagehelper.PageInfo;
importcom.kkb.kkbcommon.api.CommonPage;
importcom.kkb.kkbcommon.api.CommonResult;
importcom.kkb.kkbportal.domain.ums.User;
importcom.kkb.kkbportal.service.UserService;
importio.swagger.annotations.Api;
importio.swagger.annotations.ApiImplicitParam;
importio.swagger.annotations.ApiImplicitParams;
importio.swagger.annotations.ApiOperation;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.http.ResponseEntity;
importorg.springframework.validation.annotation.Validated;
importorg.springframework.web.bind.annotation.
;
importjava.util.List;
@RestController
@Api(tags=“用户管理”,description=“用户管理”)
@RequestMapping("/user")
publicclassUserController{
@Autowired
privateUserServiceuserService;
@ApiOperation(value=“登录”,notes=“登录接口”)
@ApiImplicitParam(name=“condition”,value=“用户登录所需信息”,dataType=“User”)
@PostMapping("/login")
publicCommonResultlogin(@RequestBody@ValidatedUsercondition){
userService.userLogin(condition);
returnCommonResult.success(null,“登录成功”);
}
@ApiOperation(value=“注册”,notes=“注册接口”)
@ApiImplicitParam(name=“condition”,value=“用户注册所需信息”,dataType=“User”)
@PostMapping("/register")
publicCommonResultregister(@RequestBody@ValidatedUseruser){
userService.userRegister(user);
returnCommonResult.success(null,“注册成功”);
}
@ApiOperation(value=“用户信息分页查询”,notes=“用户分页查询接口”)
@ApiImplicitParams({
@ApiImplicitParam(name=“condition”,value=“用户筛选条件”,dataType=
“User”),
@ApiImplicitParam(name=“pageNum”,value=“当前页数”,defaultValue=“1”,
dataType=“int”),
@ApiImplicitParam(name=“pageSize”,value=“每页页数”,defaultValue=“10”,
dataType=“int”)
})
@PostMapping("/query/page")
publicCommonResult<CommonPage>listPage(@RequestBodyUsercondition,
@RequestParam(defaultValue=
“1”)IntegerpageNum,
@RequestParam(defaultValue=
“10”)IntegerpageSize){
PageInfopage=userService.selectPage(condition,pageNum,pageSize);
System.out.println(page.getList());
CommonPagecommonPage=CommonPage.restPage(page.getList());
returnCommonResult.success(commonPage,“查询成功”);
}
@ApiOperation(value=“根据用户id添加角色”,notes=“用户-角色关系添加接口”)
@ApiImplicitParams({
@ApiImplicitParam(name=“userId”,value=“用户id”,dataType=“long”),
@ApiImplicitParam(name=“roleId”,value=“角色id”,dataType=“long”)
})
@PostMapping("/add/role")
publicResponseEntityselectRoleByUserId(@RequestParam(“userId”)LonguserId,
@RequestParam(“roleId”)LongroleId){
userService.selectRoleByUserId(userId,roleId);
returnResponseEntity.ok(“添加用户角色关系成功”);
}
@ApiOperation(value=“根据用户id查找用户信息”,notes=“根据id查询用户信息接口
“)
@ApiImplicitParams(@ApiImplicitParam(name=“id”,value=“用户id”,dataType=“long”))
@GetMapping(”/{id}”)
publicCommonResultselectUserById(@PathVariable(“id”)Longid){
Useruser=userService.selectUserById(id);
returnCommonResult.success(user,“查询成功”);
}
@ApiOperation(value=“根据用户id修改用户”,notes=“用户修改接口”)
@ApiImplicitParams({
@ApiImplicitParam(name=“id”,value=“用户id”,dataType=“long”),
@ApiImplicitParam(name=“user”,value=“用户id”,dataType=“User”)
})
@PutMapping("/update/{id}")
publicCommonResultupdateUserById(@PathVariable(“id”)Longid,@RequestBody
Useruser){
userService.updateById(id,user);
returnCommonResult.success(null,“修改成功”);
}
@ApiOperation(value=“根据用户id进行逻辑删除”,notes=“用户删除接口”)
@ApiImplicitParam(name=“id”,value=“用户id”,dataType=“long”)
@DeleteMapping("/delete/{id}")
publicCommonResultdeleteUserById(@PathVariable(“id”)Longid){
userService.deleteById(id);
returnCommonResult.success(null,“删除成功”);
}
@ApiOperation(value=“用户信息列表查询”,notes=“用户列表查询接口”)
@ApiImplicitParam(name=“condition”,value=“用户筛选条件”,dataType=“User”)
@PostMapping("/query/list")
publicCommonResult<List>list(@RequestBodyUsercondition){
Listpage=userService.selectByCondition(condition);
System.out.println(page);
returnCommonResult.success(page,“查询成功”);
}
@ApiOperation(value=“发送验证码”,notes=“用户点击获取验证码接口”)
@ApiImplicitParam(name=“phoneNumber”,value=“用户手机号”,dataType=“String”)
@PostMapping("/password")
publicResponseEntitysendSMSCode(@RequestParam(“phoneNumber”)String
phoneNumber){
userService.forgetPassword(phoneNumber);
returnResponseEntity.ok(“发送验证码成功”);
}
@ApiOperation(value=“根据验证码验证账号”,notes=“验证码登录-用户点击确定接口
“)
@ApiImplicitParams({
@ApiImplicitParam(name=“phoneNumber”,value=“用户手机号”,dataType=
“String”),
@ApiImplicitParam(name=“code”,value=“验证码”,dataType=“String”)
})
@PostMapping(”/password/verification”)
publicCommonResultsendSMSCode(@RequestParam(“phoneNumber”)String
phoneNumber,@RequestParam(“code”)Stringcode){
Useruser=userService.smsCodeVerify(phoneNumber,code);
returnCommonResult.success(user,“验证码登录成功”);
}
}
##四,学习了git上传自己创建的分支,和拉取分支
第1步:同步远程仓库代码:gitpull
第2步:查看当前状态:gitstatus
第3步:提交代码到本地git缓存区:gitadd
第4步:推送代码到本地git库:gitcommit
第5步:提交本地代码到远程仓库:gitpush
##五,项目总结
1.通过本次项目,我认为团队协作开发能力很重要,很多的问题和项目细节需要一起商量解
决,一个人很难想的很周到。
2.做项目最开始一定要把需求分析清楚,否则到后面遇到的问题越多
3.在编写过程中要进行测试,以防错误更多
4.不明白的地方要主动通过查资料或视频学习
5.不会编写一定要厚着脸皮试着编写,刚开始很痛苦,到后面就好些了
##六,《Java开发手册》读书笔记
1.代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
2.所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。说
明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,纯拼音命名方式更要
避免采用。正例:ali/alibaba/taobao/cainiao/aliyun/youku/hangzhou等国际通用的名
称,可视同英文。
3.常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
4.避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使
可读性降低。
5.如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。
6.各层命名规约:
A)Service/DAO层方法命名规约
1)获取单个对象的方法用get做前缀。
2)获取多个对象的方法用list做前缀,复数结尾,如:listObjects。
3)获取统计值的方法用count做前缀。
4)插入的方法用save/insert做前缀。
5)删除的方法用remove/delete做前缀。
6)修改的方法用update做前缀。
B)领域模型命名规约
1)数据对象:xxxDO,xxx即为数据表名。
2)数据传输对象:xxxDTO,xxx为业务领域相关的名称。
7.不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。
8.在long或者Long赋值时,数值后使用大写的L,不能是小写的l,小写容易跟数字混淆,
造成误解。
9.如果是大括号内为空,则简洁地写成{}即可,大括号中间无需换行和空格;如果是非空代
码块则:
1)左大括号前不换行。
2)左大括号后换行。
3)右大括号前换行。
4)右大括号后还有else等代码则不换行;表示终止的右大括号后必须换行。
10.避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成
本,直接用类名来访问即可。
11.任何货币金额,均以最小货币单位且整型类型来进行存储。
12.在日期格式中分清楚大写的M和小写的m,大写的H和小写的h分别指代的意义。说
明:日期格式中的这两对字母表意如下:1)表示月份是大写的M;
2)表示分钟则是小写的m;
3)24小时制的是大写的H;
4)12小时制的则是小写的h。
13.ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常:
java.util.RandomAccessSubListcannotbecasttojava.util.ArrayList。
14.利用Set元素唯一的特性,可以快速对一个集合进行去重操作,避免使用List的contains()
进行遍历去重或者判断包含操作。
15.多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出
的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
16.velocity调用POJO类的属性时,直接使用属性名取值即可,模板引擎会自动按规范调用
POJO的getXxx(),如果是boolean基本数据类型变量(boolean命名不需要加is前缀),会自
动调用isXxx()方法。
17.Java类库中定义的可以通过预检查方式规避的RuntimeException异常不应该通过catch
的方式来处理,比如:NullPointerException,IndexOutOfBoundsException等等。说明:无法
通过预检查的异常除外,比如,在解析字符串形式的数字时,可能存在数字格式错误,不得
不通过catchNumberFormatException来实现。
18.可以使用warn日志级别来记录用户输入参数错误的情况,避免用户投诉时,无所适从。
如非必要,请不要在此场景打出error级别,避免频繁报警。
19.用户请求传入的任何参数必须做有效性验证。
说明:忽略参数校验可能导致:
⚫pagesize过大导致内存溢出
⚫恶意orderby导致数据库慢查询
⚫缓存击穿
⚫SSRF
⚫任意重定向
⚫SQL注入,Shell注入,反序列化注入
⚫正则输入源串拒绝服务ReDoS
Java代码用正则来验证客户端的输入,有些正则写法验证普通用户输入没有问题,但是如
果攻击人员使用的是特殊构造的字符串来验证,有可能导致死循环的结果。
20.表必备三字段:id,gmt_create,gmt_modified。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用python中的pymsql完成如下:表结构与数据创建 1. 建立 `users` 表和 `orders` 表。 `users` 表有用户ID、用户名、年龄字段,(id,name,age) `orders` 表有订单ID、订单日期、订单金额,用户id字段。(id,order_date,amount,user_id) 2 两表的id作为主键,`orders` 表用户id为users的外键 3 插入数据 `users` (1, '张三', 18), (2, '李四', 20), (3, '王五', 22), (4, '赵六', 25), (5, '钱七', 28); `orders` (1, '2021-09-01', 500, 1), (2, '2021-09-02', 1000, 2), (3, '2021-09-03', 600, 3), (4, '2021-09-04', 800, 4), (5, '2021-09-05', 1500, 5), (6, '2021-09-06', 1200, 3), (7, '2021-09-07', 2000, 1), (8, '2021-09-08', 300, 2), (9, '2021-09-09', 700, 5), (10, '2021-09-10', 900, 4); 查询语句 1. 查询订单总金额 2. 查询所有用户的平均年龄,并将结果四舍五入保留两位小数。 3. 查询订单总数最多的用户的姓名和订单总数。 4. 查询所有不重复的年龄。 5. 查询订单日期在2021年9月1日至9月4日之间的订单总金额。 6. 查询年龄不大于25岁的用户的订单数量,并按照降序排序。 7. 查询订单总金额排名前3的用户的姓名和订单总金额。 8. 查询订单总金额最大的用户的姓名和订单总金额。 9. 查询订单总金额最小的用户的姓名和订单总金额。 10. 查询所有名字中含有“李”的用户,按照名字升序排序。 11. 查询所有年龄大于20岁的用户,按照年龄降序排序,并只显示前5条记录。 12. 查询每个用户的订单数量和订单总金额,并按照总金额降序排序。
最新发布
06-03

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值