spring boot 之 kotlin语言开发,用一次就想放弃Java,爽歪歪~~~

2023-11-18

废话少说,上视频

spring boot 之 kotlin用一次就想放弃java,爽歪歪~~~

1、启动入口:

@SpringBootApplication
@EnableDiscoveryClient
class TawuziAuthServerDbApplication

fun main(args: Array<String>) {
    runApplication<TawuziAuthServerDbApplication>(*args)
}

说明

kotlin中的method,语法为

	fun 函数名(参数1,参数2): 返回值 {
	      函数体
	}

是不是比Java简单了

2、控制器controller:

@Controller
class MessagesController {

    @ResponseBody
    @GetMapping("/messages")
    fun getMessages(): Array<String>? {
        return arrayOf("Message 1", "Message 2", "Message 3")
    }

    @ResponseBody
    @GetMapping("/user")
    fun user(): Jwt? {
        val principal = SecurityContextHolder.getContext().authentication.principal as Jwt
        println(principal)
        // 查询数据库获取用户信息
        return principal
    }
}

3、依赖注入:

类与方法参数均可注入

@Configuration(proxyBeanMethods = false)
class AuthorizationServerConfig(
    @Autowired val passwordEncoder: PasswordEncoder,
    @Value("\${diy.secure.jwk.fpath}") val jwkFile: String,
    @Value("\${diy.secure.jwk.keypass}") val jwkKeypass: String,
    @Value("\${diy.secure.jwk.storepass}") val jwkStorepass: String,
    @Value("\${diy.secure.jwk.alias}") val jwkAlias: String
) {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Throws(
        Exception::class
    )
    fun authorizationServerSecurityFilterChain(http: HttpSecurity): SecurityFilterChain {
        val authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer()
        authorizationServerConfigurer
            .authorizationEndpoint { authorizationEndpoint ->
                authorizationEndpoint
                    .consentPage(CUSTOM_CONSENT_PAGE_URI)
            }
            .oidc(Customizer.withDefaults())
        val endpointsMatcher: RequestMatcher = authorizationServerConfigurer.endpointsMatcher
        http
            .csrf().disable().cors().disable()
            .securityMatcher(endpointsMatcher)
            .authorizeHttpRequests {authorize ->
                authorize
//                    .requestMatchers("/auth/.well-known/**").permitAll()
                    .anyRequest().authenticated()
            }
            .csrf {csrf ->
                csrf.ignoringRequestMatchers(endpointsMatcher)
            }
            .exceptionHandling {exceptions ->
                exceptions.authenticationEntryPoint(LoginUrlAuthenticationEntryPoint("/login"))
            }
            .oauth2ResourceServer { obj ->
                obj.jwt()
            }.apply(authorizationServerConfigurer)
        return http.build()
    }

    // @formatter:off
    @Bean
    fun registeredClientRepository(jdbcTemplate: JdbcTemplate?): RegisteredClientRepository {
        val registeredClient: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("messaging-client")
            .clientSecret("{noop}secret")
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
            .redirectUri("http://127.0.0.1:8080/authorized")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .scope("message.read")
            .scope("message.write")
            .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
            .build()
        val registeredClient1: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("messaging-client1")
            .clientSecret(passwordEncoder.encode("secret"))
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .redirectUri("http://127.0.0.1:8081/login/oauth2/code/messaging-client-oidc1")
            .redirectUri("http://127.0.0.1:8081/authorized")
            .redirectUri("http://127.0.0.1:8081/code")
            .redirectUri("http://127.0.0.1:8081/cb")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .scope("message.read")
            .scope("message.write")
            .clientSettings(
                ClientSettings
                    .builder()
                    .requireAuthorizationConsent(false)
                    .build()
            )
            .build()
        val registeredClient4: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("messaging-client4")
            .clientSecret(passwordEncoder.encode("secret"))
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .redirectUri("http://127.0.0.1:8084/login/oauth2/code/messaging-client-oidc4")
            .redirectUri("http://127.0.0.1:8084/authorized")
            .redirectUri("http://127.0.0.1:8084/backcb")
            .redirectUri("http://127.0.0.1:8084/cb")
            .redirectUri("http://127.0.0.1:8084/code")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .scope("message.read")
            .scope("message.write")
            .clientSettings(
                ClientSettings
                    .builder()
                    .requireAuthorizationConsent(false)
                    .build()
            )
            .build()
        val mobileRegisteredClient4: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("mobile-messaging-client4")
            .clientSecret(passwordEncoder.encode("secret"))
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .redirectUri("http://192.168.1.6:8100/login/oauth2/code/mobile-messaging-client-oidc4")
            .redirectUri("http://192.168.1.6:8100/authorized")
            .redirectUri("http://192.168.1.6:8100/backcb")
            .redirectUri("http://192.168.1.6:8100/cb")
            .redirectUri("http://192.168.1.6:8100/code")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .scope("message.read")
            .scope("message.write")
            .clientSettings(
                ClientSettings
                    .builder()
                    .requireAuthorizationConsent(false)
                    .build()
            )
            .build()

        val registeredClientLogin: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("messaging-client-login")
            .clientSecret(passwordEncoder.encode("secret"))
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .redirectUri("http://127.0.0.1:9010/login/oauth2/code/messaging-client-oidc-login")
            .redirectUri("http://127.0.0.1:9010/authorized")
            .redirectUri("http://127.0.0.1:9010/code")
            .redirectUri("http://127.0.0.1:9010/cb")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .scope("message.read")
            .scope("message.write")
            .clientSettings(
                ClientSettings
                    .builder()
                    .requireAuthorizationConsent(false)
                    .build()
            )
            .build()

        val registeredClientRepository = JdbcRegisteredClientRepository(jdbcTemplate)
        return registeredClientRepository
    }

    // @formatter:on
    @Bean
    fun authorizationService(
        jdbcTemplate: JdbcTemplate?,
        registeredClientRepository: RegisteredClientRepository?
    ): OAuth2AuthorizationService {
        return JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository)
    }

    @Bean
    fun authorizationConsentService(
        jdbcTemplate: JdbcTemplate?,
        registeredClientRepository: RegisteredClientRepository?
    ): OAuth2AuthorizationConsentService {
        return JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository)
    }

    @Bean
    @Throws(Exception::class)
    fun jwkSource(): JWKSource<SecurityContext> {
        val keyStore = KeyStore.getInstance(
            ClassPathResource(
                jwkFile!!
            ).file, jwkStorepass!!.toCharArray()
        )
        val rsaKey: RSAKey = RSAKey.load(keyStore, jwkAlias, jwkStorepass.toCharArray())
        return JWKSource<SecurityContext> { jwkSelector: JWKSelector, securityContext: com.nimbusds.jose.proc.SecurityContext? ->
            jwkSelector.select(
                JWKSet(rsaKey)
            )
        }
    }

    @Bean
    fun jwtDecoder(jwkSource: JWKSource<com.nimbusds.jose.proc.SecurityContext?>?): JwtDecoder {
        return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource)
    }

    @Bean
    fun authorizationServerSettings(): AuthorizationServerSettings {
        return AuthorizationServerSettings.builder().issuer("http://banang.com:9000").build()
    }

    companion object {
        private const val CUSTOM_CONSENT_PAGE_URI = "/oauth2/consent"
    }
}

总结:

kotlin、flutter、Swift语言,差不多算是最近几年新出得语言,
虽然Google、苹果、jetbrains都在强力推荐新语言,
致力于将各自的语言应用到移动、服务器、前端等领域,
但从目前发展来看,kotlin无疑是发展最好的,
已经可以实现在Android、iOS端、web端(替换Java)稳定开发。
如果行业都在跟进的话,不出三年,Java有可能走向衰落。

Stay curious and keep learning。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring boot 之 kotlin语言开发,用一次就想放弃Java,爽歪歪~~~ 的相关文章

随机推荐

  • Jenkins持续集成项目实践 —— 基于Python Selenium自动化测试(二)

    上一篇讲了如何搭建jenkins 这篇主要讲 怎么将自动化代码与jenkins衔接起来 jenkins上运行的两种方式 第一种 在jenkins上面运行本地代码 操作如下 新建项目 项目名称根据自己项目情况填写并选择自由模式 进行配置根据如
  • LaTeX中插入matlab代码(可添加中文注释)的几种方法

    最近在用LaTeX写文件时 需要插入matlab代码 但是matlab代码编写时没有注意到注释为中文所带来的不便 导致在编写LaTeX文件时总是报错 经查阅网上有关这方面的资料和自己不断地尝试之后 总结其中的方法如下 使用matlab的mc
  • 【满分】【华为OD机试真题2023 JS】字母组合

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 字母组合 知识点回溯 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 每个数字对应多个字母 对应关系如下 0 a b c 1 d e f 2 g h i 3 j
  • Android MVP 详解(上)

    作者 李旺成 时间 2016年4月3日 Android MVP 详解 下 已经发布 欢迎大家提建议 MVP 在 Android 上的使用其实已经有挺长一段时间了 长到似乎有点 过时 了 目前风头正劲的是MVVM 那为什么现在还要讲 MVP
  • tf.nn.atrous_conv2d如何实现空洞卷积?

    转载自 https blog csdn net mao xiao feng article details 78003730 介绍 关于空洞卷积的理论可以查看以下链接 这里我们不详细讲理论 1 Long J Shelhamer E Darr
  • 业务实战中如何利用MySQL函数来解决

    随着我们业务越来越复杂的情况下 完全基于java后台来解决首先是很麻烦 而且性能带来降低 代码的可读性下降 这个时候就需要一些MySQL的函数来解决了 这篇文章对于常见的MySQL函数不予介绍 concat函数 使用方法 CONCAT st
  • Flink设置Source数据源使用kafka获取数据

    流处理说明 有边界的流bounded stream 批数据 无边界的流unbounded stream 真正的流数据 Source 基于集合 package com pzb source import org apache flink ap
  • I Hate It

    很多学校流行一种比较的习惯 老师们很喜欢询问 从某某到某某当中 分数最高的是多少 这让很多学生很反感 不管你喜不喜欢 现在需要你做的是 就是按照老师的要求 写一个程序 模拟老师的询问 当然 老师有时候需要更新某位同学的成绩 Input 本题
  • volatile和synchronized的区别

    共性 volatile与synchronized都用于保证多线程中数据的安全 区别 1 volatile修饰的变量 jvm每次都从主存 主内存 中读取 而不会从寄存器 工作内存 中读取 而synchronized则是锁住当前变量 同一时刻只
  • 第一次 openwrt源码下载编译

    openwrt 学习记录 第一次 openwrt源码下载编译 MT7620开发板 安装虚拟机VMware 安装Ubnutu 先进入root账户 topeet ubuntu su 输入密码 1 搭建编译环境 参考 https blog csd
  • maven的使用

    目录 一 maven基本参数 二 maven基础结构 三 mvn的打包和运行 一 maven基本参数 groupId 是指项目里面的标识 一般写法是com mycom myapp 其中mycom是指你公司的域名 例如com google m
  • YOLOv5+PaddleOCR手写签名识别

    YOLOv5 PaddleOCR手写签名识别 介绍 参加了一个中国移动的比赛 比赛的数据集是一个工单 上面有多个人的签名还有手写的时间 因为主办方不允许数据公开 所以在这一系列博客中 我主要讲一下实现的思路 在YOLO演示的时候我会用其他的
  • 查看linux服务器内存信息

    查看服务器内存信息 dmidecode grep P A5 Memory s Device grep Size root localhost home dmidecode grep P A5 Memory s Device grep Siz
  • 【leetcode刷题】--- 21.合并两个有序链表(C++递归)

    21 合并两个有序链表 原题链接 https leetcode cn com problems merge two sorted lists 题目 将两个升序链表合并为一个新的 升序 链表并返回 新链表是通过拼接给定的两个链表的所有节点组成
  • 关于ApplicationContext的getBean()方法发现

    假定 Son类实现father接口 在Son类定义声明式事务后 通过ApplicationContext接口的getBean Class arg0 方法获取注入好的bean会报异常 方法参数Son class Son已声明bean org
  • 18. 线性代数 - 线性变换

    文章目录 线性空间 线性变换 线性变换的几何意义 特征值与特征向量 NumPy的矩阵操作 Hi 你好 我是茶桁 经历了几节线性代数课程之后 终于咱们到了最后一节课了 本节课的内容说多不多 说少也不少 我们先是要理解一下线性空间和线性变换 并
  • uml之Robustness Diagram

    Robustness Diagram 从需求分析到架构设计 转载自 http www dotblogs com tw jed archive 2010 11 21 robustness diagram aspx 什么是Robustness
  • Java IO流

    目录 一 认识Java的流 二 使用字节流读写文本文件 三 使用字符流读写文本文件 四 读写二进制文件 五 序列化和反序列化 六 总结 一 认识Java的流 1 读文件是指把文件中的数据读取到内存中 2 写文件是把内存中的数据写到文件中 3
  • 2023高教社杯 国赛数学建模E题思路 - 黄河水沙监测数据分析

    1 赛题 E 题 黄河水沙监测数据分析 黄河是中华民族的母亲河 研究黄河水沙通量的变化规律对沿黄流域的环境治理 气候变 化和人民生活的影响 以及对优化黄河流域水资源分配 协调人地关系 调水调沙 防洪减灾 等方面都具有重要的理论指导意义 附件
  • spring boot 之 kotlin语言开发,用一次就想放弃Java,爽歪歪~~~

    废话少说 上视频 spring boot 之 kotlin用一次就想放弃java 爽歪歪 1 启动入口 SpringBootApplication EnableDiscoveryClient class TawuziAuthServerDb