栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

学生程序设计能力提升平台源码分析(三)Controller层源码分析之收尾篇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

学生程序设计能力提升平台源码分析(三)Controller层源码分析之收尾篇

概述

本篇博客继续上次的话题,对项目Controller层源码分析进行收尾

源码

源码如下:

​


@RestController
@RequestMapping("/problemset")
public class ProblemsetController {

    @Autowired
    private ProblemsetService problemsetService;

    @Autowired
    private ProblemService problemService;

    private final Logger log = LoggerFactory.getLogger(ProblemController.class);


    @PostMapping("/getProblemset")
    @PreAuthorize("hasRole('ROLE_COMMON')")
    public ResultEntity getProblemset(@RequestParam("id") int id) {
        try {
            Problemset problemset = problemsetService.getProblemset(id);
            List problemList = problemsetService.getProblemList(id);
            problemset.setProblems(problemList);
            return ResultEntity.success("题目集", problemset);
        } catch (Exception e) {
            log.error("查看题目集错误", e);
            return ResultEntity.error("查看题目集错误,请重试");
        }
    }

}

​

在上一篇博客中已经分析了@Autowired实现原理,slf4j日志,@PostMapping实现原理等

下面我们将对剩余关键点进行分析,其实就是对:
1.@PreAuthorize("hasRole('ROLE_COMMON')")

2.@RequestParam("id") int id

3. return ResultEntity

三个部分进行分析

@PreAuthorize实现原理

@PreAuthorize注解来自于SpringSecurity,是SpringSecurity提供的权限安全认证注解。是在进入方法前进行权限验证,@PreAuthorize 声明这个方法所需要的权限表达式

使用方法

hasRole:

角色授权:授权代码,在我们返回的UserDetails的Authority需要加ROLE_前缀,Controller上使用时不要加前缀,例如:

hasAuthority:

权限授权:用户自定义的权限,返回的UserDetails的Authority只要与这里匹配就可以,这里不需要加ROLE_,名称保持一至即,例如:

其余使用不如上面两个频繁:

源代码
package org.springframework.security.access.prepost;

import java.lang.annotation.documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@documented
public @interface PreAuthorize {
    String value();
}
分析原理

这里我们以hasAuthority()方法为示例,其余方法的原理大同小异:
原理就是:根据这个注解所需要的权限,再和当前登录的用户角色所拥有的权限对比,如果用户的角色权限集Set中有这个权限,则放行;没有,拒绝

所需要的权限由注解参数传递,登录角色拥有的权限由spring security控制,在用户login的时候已经获取并保存

详细代码流程:

hasAuthority代码流程

@RequestParam实现原理 使用方法

@RequestParam可以将请求参数绑定到控制器的方法参数上,规定了方法所接受的参数列表

语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)

value:参数名
required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值

例子:

源代码
package org.springframework.web.bind.annotation;

import java.lang.annotation.documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "nttnttnue000ue001ue002nttttn";
}
分析原理

简单来说就是通过 request.getParameter() 方法去获取参数值,然后对 @RequestParam 中的属性进行比对,实现由注解到底层代码的封装

具体封装流程:

@RequestParam 代码流程

ResultEntity实现原理 使用方法

作为controller层返回参数的实体类,可以return resultEntity.success()或者return resultEntity.error()控制返回的类型,通过不同的参数列表实现不同的返回效果,例如:
 

return ResultEntity.success("公开题目集", problemsets);

return ResultEntity.error("查看公开题目集错误,请重试");

return ResultEntity.success("题目集添加成功");

等等

源代码
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;

public class ResultEntity {
    @JSonField(ordinal = 1)
    private int code;
    @JSonField(ordinal = 2)
    private String message;
    @JSonField(ordinal = 3)
    private Object data;

    public ResultEntity(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public static ResultEntity success() {
        return new ResultEntity(0, "success", true);
    }

    public static ResultEntity success(String message) {
        return new ResultEntity(0, message, null);
    }

    public static ResultEntity success(String message, Object data) {
        return new ResultEntity(0, message, data);
    }

    public static ResultEntity data(Object data) {
        return success("success", data);
    }

    public static ResultEntity data(){
        return success("success");
    }

    public static ResultEntity error(String message) {
        return new ResultEntity(-1, message, null);
    }

    public static ResultEntity error(String message, Object data) {
        return new ResultEntity(-1, message, data);
    }

    public static ResultEntity error(int code, String message) {
        return new ResultEntity(code, message, null);
    }

    public static ResultEntity error(StatusCode entity){
        return new ResultEntity(entity.getCode(), entity.getMessage(), null);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return JSONObject.toJSonString(this);
    }
}
分析原理

内置code,message,data的实体类,通过不同的构造参数实现不同的数据封装,并作为返回体返回请求的结果

总结

controller层的源码分析就到此为止了,可以看出来一些注解和类的底层实现机制还是比较复杂的,了解其实现原理对我们提高代码分析和开发能力有一定帮助。

下一篇分析预计会对service层代码进行分析,感谢阅读。

参考资料

@RequestParam注解使用_一叶知秋-CSDN博客_@requestparam

Spring Security - @PreAuthorize安全表达式hasRole、hasAuthority区别_LeoSong121的博客-CSDN博客Spring Security @PreAuthorize 权限控制的原理_u010227042的博客-CSDN博客Spring Security - @PreAuthorize安全表达式hasRole、hasAuthority区别_LeoSong121的博客-CSDN博客

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/348833.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号