博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React.js 集成 Spring Boot 开发 Web 应用
阅读量:6161 次
发布时间:2019-06-21

本文共 10027 字,大约阅读时间需要 33 分钟。

React.js 集成 Spring Boot 开发 Web 应用

1. 创建工程

image.png
reakt$ tree ..├── build.gradle├── gradle│   └── wrapper│       ├── gradle-wrapper.jar│       └── gradle-wrapper.properties├── gradlew├── gradlew.bat└── src    ├── main    │   ├── kotlin    │   │   └── com    │   │       └── reaktboot    │   │           └── reakt    │   │               └── ReaktApplication.kt    │   └── resources    │       ├── application.properties    │       ├── static    │       └── templates    └── test        └── kotlin            └── com                └── reaktboot                    └── reakt                        └── ReaktApplicationTests.kt16 directories, 8 files

导入 IDEA 中

image.png

2. 配置数据源 application-dev.properties

#mysqlspring.datasource.url=jdbc:mysql://localhost:3306/reakt?useUnicode=true&characterEncoding=UTF8&useSSL=falsespring.datasource.username=rootspring.datasource.password=rootspring.datasource.driverClassName=com.mysql.jdbc.Driver# Specify the DBMSspring.jpa.database=MYSQL# Show or not log for each sql queryspring.jpa.show-sql=true# Hibernate ddl auto (create, create-drop, update)spring.jpa.hibernate.ddl-auto=create-drop#spring.jpa.hibernate.ddl-auto=update# stripped before adding them to the entity manager)spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

3. 创建User,Role 表

image.png
package com.reaktboot.reakt.entityimport javax.persistence.*/** * Created by jack on 2017/4/29. */@Entityclass User {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    var id: Long = -1    @Column(length = 50, unique = true)    var username: String = ""    var password: String = ""    @ManyToMany(targetEntity = Role::class, fetch = FetchType.EAGER)    lateinit var roles: Set
override fun toString(): String { return "User(id=$id, username='$username', password='$password', roles=$roles)" }}package com.reaktboot.reakt.entityimport javax.persistence.*/** * Created by jack on 2017/4/29. */@Entityclass Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = -1 @Column(length = 50, unique = true) var role: String = "ROLE_USER"}package com.reaktboot.reakt.daoimport com.reaktboot.reakt.entity.Userimport org.springframework.data.jpa.repository.JpaRepositoryimport org.springframework.data.jpa.repository.Queryimport org.springframework.data.repository.query.Paraminterface UserDao : JpaRepository
{ @Query(""" select a from #{#entityName} a where a.username = :username """) fun findByUsername(@Param("username") username: String): User?}package com.reaktboot.reakt.daoimport com.reaktboot.reakt.entity.Roleimport org.springframework.data.jpa.repository.JpaRepositoryinterface RoleDao : JpaRepository
{}

4. 实现登陆权限校验

WebSecurityConfig

package com.reaktboot.reaktimport com.reaktboot.reakt.handler.MyAccessDeniedHandlerimport com.reaktboot.reaktservice.MyUserDetailServiceimport org.springframework.context.annotation.Beanimport org.springframework.context.annotation.Configurationimport org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilderimport org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurityimport org.springframework.security.config.annotation.web.builders.HttpSecurityimport org.springframework.security.config.annotation.web.configuration.EnableWebSecurityimport org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapterimport org.springframework.security.core.userdetails.UserDetailsServiceimport org.springframework.security.crypto.bcrypt.BCryptPasswordEncoderimport org.springframework.security.web.access.AccessDeniedHandler/**prePostEnabled :决定Spring Security的前注解是否可用 [@PreAuthorize,@PostAuthorize,..]secureEnabled : 决定是否Spring Security的保障注解 [@Secured] 是否可用jsr250Enabled :决定 JSR-250 annotations 注解[@RolesAllowed..] 是否可用. */@Configuration@EnableWebSecurity// 开启 Spring Security 方法级安全@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)class WebSecurityConfig : WebSecurityConfigurerAdapter() {    @Bean    fun myAccessDeniedHandler(): AccessDeniedHandler {        return MyAccessDeniedHandler("/403")    }    @Bean    override fun userDetailsService(): UserDetailsService {        return MyUserDetailService()    }    @Throws(Exception::class)    override fun configure(http: HttpSecurity) {        http.csrf().disable()        http.authorizeRequests()            .antMatchers("/", // 首页不拦截                    "/css/**",                    "/fonts/**",                    "/js/**",                    "/images/**" // 不拦截静态资源            ).permitAll()            .anyRequest().authenticated()            .and()            .formLogin()            //.loginPage("/login")// url 请求路径,对应 LoginController 里面的 @GetMapping("/login")            .usernameParameter("username")            .passwordParameter("password")            .defaultSuccessUrl("/main").permitAll()            .and()            .exceptionHandling().accessDeniedHandler(myAccessDeniedHandler())//            .exceptionHandling().accessDeniedPage("/403")            .and()            .logout().permitAll()        http.logout().logoutSuccessUrl("/")    }    @Throws(Exception::class)    override fun configure(auth: AuthenticationManagerBuilder) {        //AuthenticationManager 使用我们的 lightSwordUserDetailService 来获取用户信息        auth.userDetailsService(userDetailsService())            .passwordEncoder(passwordEncoder())    }    /**     * 密码加密算法     *     * @return     */    @Bean    fun passwordEncoder(): BCryptPasswordEncoder {        return BCryptPasswordEncoder();    }}

MyUserDetailService

package com.reaktboot.reaktserviceimport com.reaktboot.reakt.dao.UserDaoimport org.slf4j.LoggerFactoryimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.security.core.authority.SimpleGrantedAuthorityimport org.springframework.security.core.userdetails.UserDetailsimport org.springframework.security.core.userdetails.UserDetailsServiceimport org.springframework.security.core.userdetails.UsernameNotFoundExceptionimport org.springframework.stereotype.Service@Serviceclass MyUserDetailService : UserDetailsService {    val logger = LoggerFactory.getLogger(MyUserDetailService::class.java)    @Autowired lateinit var userDao: UserDao    override fun loadUserByUsername(username: String): UserDetails {        val user = userDao.findByUsername(username) ?: throw  UsernameNotFoundException(username + " not found")        logger.info("user = {}", user)        val roles = user.roles        val authorities = mutableSetOf
() roles.forEach { authorities.add(SimpleGrantedAuthority(it.role)) } return org.springframework.security.core.userdetails.User( // 此处为了区分我们本地系统中的 User 实体类,特意列出userdetails 的 User 类的全路径 username, user.password, authorities ) }}

5. 前端使用 React.js 开发: 目录结构

我们使用 nowa:

使用文档:

PC 前端组件库:

image.png

6. 创建 React 前端工程

前端应用工程目录放到 /Users/jack/KotlinSpringBoot/reakt/src/main/resources 目录下:

image.png

前端目录结构如下:

image.png
~/KotlinSpringBoot/reakt/src/main/resources/reakt$ lsabc.json          mock              package-lock.json srchtml              node_modules      package.json      webpack.config.js~/KotlinSpringBoot/reakt/src/main/resources/reakt$ tree src/src/├── app│   ├── app.js│   ├── app.less│   ├── db.js│   ├── util.js│   └── variables.js├── components│   ├── search-data│   │   ├── SearchData.jsx│   │   └── index.js│   └── search-word│       ├── SearchWord.jsx│       └── index.js├── images│   └── README.md└── pages    ├── demo    │   ├── PageDemo.jsx    │   ├── PageDemo.less    │   ├── index.js    │   └── logic.js    └── home        ├── PageHome.jsx        ├── PageHome.less        ├── index.js        └── logic.js8 directories, 18 files

前端工程应用单独启动:

jack@jacks-MacBook-Air:~/KotlinSpringBoot/reakt/src/main/resources/reakt$ nowa server

Listening at http://192.168.0.104:3000

浏览器访问: http://192.168.0.104:3000

可以看到 nowa 集成的 uxcore 的样板示例工程:

image.png

nowa 使用参考:

nowa 使用的体验两大精华地方,

不需要学习webpack, 整个前端开发环境都集成了. react入门的小白最喜欢了, 我学webpack头大死了,到现在也没有搞明白. 用了nowa,我就不需要搞明白了.

掌握了nowa的脚手架模板, 整个开发效率提升2倍.

如果说react将组件的复用提高到极限,减少了重复代码的工作量. nowa的自定义脚手架,则把项目文件的复用便捷性提高到极限, 以前要复制一组文件,然后修改文件名/组件名..等等.

现在:

用 nowa init mod 创建一组函数组件

用nowa init rmod 创建一组react组件,
用nowa init page 创建自己个性化的一组文件,
用nwoa init api 创建api资源模块,

创建好了,直接可以写业务代码,不需要复制粘贴啥的了. 当然mod rmod page api 这几个都是按项目和自己习惯,定义过的模板.

gui版本,我也体验了一下, 管理项目方便了.不用去文件夹里面翻找了.

7. 前后端目录集成

image.png
image.png

Navbar.jsx

import {Component} from 'react';import './Navbar.less';const Menu = require('uxcore-menu')const SubMenu = Menu.SubMenuconst MenuItem = Menu.Itemexport default class Navbar extends Component {  static defaultProps = {}  static propTypes = {}  constructor(props) {    super(props);    this.state = {      current: '1'    }  }  handleClick(e) {    console.log('click ', e);    this.setState({      current: e.key,    });  }  render() {    return (      

Reakt

首页
快速开始
博客文章}>
选项1
选项2
选项3
选项4
关于我们
Kotlin}>
Java
Scala
Groovy
Spring Boot}>
Spring MVC
WebFlux
Security
JPA
React }>
Node.js
Reflux
ES6
); }}

参考文档:

转载地址:http://bdrfa.baihongyu.com/

你可能感兴趣的文章
微信小程序开发-框架
查看>>
redo、undo、binlog的区别
查看>>
RecycleView设置顶部分割线(记录一个坑)
查看>>
汉字转拼音 (转)
查看>>
会计基础_001
查看>>
小程序: 查看正在写的页面
查看>>
Jenkins持续集成环境部署
查看>>
MWeb 1.4 新功能介绍二:静态博客功能增强
查看>>
预处理、const与sizeof相关面试题
查看>>
爬虫豆瓣top250项目-开发文档
查看>>
有趣的数学书籍
查看>>
teamviewer 卸载干净
查看>>
eclipse的maven、Scala环境搭建
查看>>
架构师之路(一)- 什么是软件架构
查看>>
USACO 土地购买
查看>>
【原创】远景能源面试--一面
查看>>
B1010.一元多项式求导(25)
查看>>
10、程序员和编译器之间的关系
查看>>
配置 RAILS FOR JRUBY1.7.4
查看>>
修改GRUB2背景图片
查看>>