博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
前后端分离 Spring Boot + Vue 开发单页面应用 个人总结(一)
阅读量:5923 次
发布时间:2019-06-19

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

hot3.png

前后端分离 Spring Booot + Vue 开发单页面应用 个人总结(一)

2018/10/31 更新

还是跨越,因为年少无知,文章中分享的方案并不是最优解,存在很多局限的地方,因此误人子弟十分抱歉。对现在而言,我跨域的解决方案分两种。一、在开发过程中,vue提供了优雅的解决方式,即通过自身的反向代理实现(实际上我也不太清楚是基于包依赖,还是webpack或node实现),一般在配置文件配置,在你的项目中找到类似的地方
module.exports = {    dev: {	       ....		   proxyTable: {		       // 配置反向代理		   }		   ....	   }}

贴一下我的配置方式

proxyTable: {   '/api': {  // 代理转发的地址前缀以api开头,/ 代表所有请求     target: 'http://localhost:8080',    // 转发到     changeOrigin: true,     pathRewrite: {  // url重写       '^/api': ''    // 将/api前缀去掉     }   }, },

这种配置方式,后端不用做任何配置,即我后面介绍的CorsConfig是完全不需要的,而且axios的baseurl也是不需要配置的~注意,这种配置只对开发环境即dev环境生效,当npm run build之后,部署的时候实际上并不会生效。 那么在生产环境,一、如果像我后面介绍的将打包文件直接丢到springboot static下,那是不会产生跨域问题的,本来就是同源的。其次,如果单独部署,那么nginx等等都有反向代理功能,只能配置这些服务器的方向代理就ok了~

2018/01/30 更新

    关于跨域_:_在实际开发过程中,发现跨域问题并不是那么好解决的 因为Springboot安全控制框架使用了Securtiy,它的身份认证基于 JSESSIONID 而axios框架默认是不发送cookie的,因此需要在axios配置中添加

axios.defaults.withCredentials = true

然而因为跨域策略问题,Springboot后端跨域设置也要修改

@Configurationpublic class CorsConfig {    /**     允许任何域名使用     允许任何头     允许任何方法(post、get等)     */    private CorsConfiguration buildConfig() {        CorsConfiguration corsConfiguration = new CorsConfiguration();        // addAllowedOrigin 不能设置为* 因为与 allowCredential 冲突        corsConfiguration.addAllowedOrigin("http://localhost:9528");        corsConfiguration.addAllowedHeader("*");        corsConfiguration.addAllowedMethod("*");        // allowCredential 需设置为true        corsConfiguration.setAllowCredentials(true);        return corsConfiguration;    }    @Bean    public CorsFilter corsFilter() {        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();        source.registerCorsConfiguration("/**", buildConfig());        return new CorsFilter(source);    }}

前言

_    需求:_ 最近本人在学习SpringBoot,希望自己能搭一个简单的Demo应用出来,但是搭到前端的时候遇到了困惑,因为网络上大部分教程前端都是应用模板引擎thymeleaf生成的,它给我的感觉就是一个进化版的JSP,但是很明显这种开发方式已经有些落后了。现在前端越来越工程化,Angular/Vue/React等框架非常流行,所以我希望搭建一个更符合技术进步方向的前端应用(我选择了相对容易入门的Vue)。

_    问题:_ 在查阅资料过程,我发现SpringBoot和Vue相关的入门材料非常的多,但是关于两者结合的相对较少,导致踩了不少坑。在不断得试错之下,终于成功搭建了一个Demo应用,并实现一个登陆实例,因此在此总结巩固。

_    项目架构_  服务端以SpringBoot框架为核心,除提供转发到首页外,只提供RESTful接口,通过Json格式消息进行交互;前端以Vue全家桶为核心,实现SPA单页面应用,以ajax方式与服务端进行通信;前后端分离开发,因此会建两个项目,通过npm run build 打包项目(复制进)项目进行整合。

**    阅读者有一定的Java基础,SpringBoot基础,同时有一定的前端基础,Vue基础。**

好吧,这篇博客其实主要是写给我自己的

开发环境介绍

  • JDK1.8
  • Node v8.9.3
  • npm v5.5.1
  • 开发工具IDEA(安装Vue.js插件)
  • 数据库MySQL 57
  • 版本管理工具 Git

都是一些基础的开发环境,具体搭建过程略。

服务端搭建

    利用Spring Initializr 创建一个SpinrgBoot模板

image
    组名及项目名随意,添加依赖的话视需求而定,这里就添加了Web的核心依赖和一些数据库的依赖
image
    pom.xml 文件 核心依赖

org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
runtime
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
test

    然后,添加配置文件,在这里我用yml进行配置,感觉比较优雅

    application.xml 放置在resources根目录下 记得把数据库username和password和url改为自己的

# set server portserver:  port: 8888  # 配置端口  context-path: / # 项目启动地址为 localhost:8888/spring:  datasource: # set database config    url: jdbc:mysql://localhost:3306/***?useUnicode=true&characterEncoding=utf8&useSSL=false    username: *****    password: *****    driver-class-name: com.mysql.jdbc.Driver  jpa: # set jpa    database: MYSQL # specify ths DBMS    show-sql: true # show or not log for each sql query    hibernate:      ddl-auto: update # Hibernate ddl auto(create, create-drop, update)      naming: # naming strategy        strategy: org.hibernate.cfg.ImprovedNamingStrategy    properties:      hibernate: # stripped before adding them to entity manager        dialect: org.hibernate.dialect.MySQL5Dialect  aop: #设置aop,aop依赖添加后默认是启用的    proxy-target-class: true

    创建目录仅结构,目录结构参考了网络上的案例和自己的习惯,供参考

image

    Demo项目仅实现登陆实例,因此数据实体只需要一个User就好,User类上需加 注解,代表这是实体类,交由Hibernate进行管理;同时,我使用了spring boot核心依赖之一的validation作为参数验证框架,验证方法会在controller中实现;详细代码参阅 entity/SysUser 如果全贴代码的话,篇幅会非常的长,所以详细代码请到github上看源码,都带有详细的注释

    顺便把SysUser的Dao层接口实现

/** * 用户Dao层 * 继承JapRepository,可以实现一些默认方法,如save/findAll/findOne/delete/count/exists 等 * Created by bekey on 2017/12/9. */public interface SysUserRepository extends JpaRepository
{ //...}

    我们在SysUserRepository中只添加一个findFirstByNameAndPassword方法就够了,详细源码参见 repository/SysUserRepository

    接着,搭建服务层,服务层遵循服务接口 + 实现 的模式,我们现在还没有创建用户,那么就提供 saveUser 和 checkLogin 两个服务好啦,详细代码参阅 service/SysUserService 和 service/SysUserServiceImpl

    服务层实现方式都比较简单粗暴,通过修改实现类可以增加密码加密等更多功能

    然后,该搭建控制层了,为控制类添加 @RestController 就可以实现该类下所有方法都会自动以Json格式返回数据啦!

/** *  用户控制层 * . @RestController 该类下所有返回值默认以json格式进行返回   * . @RequestMapping 匹配url地址 /user   * . @Validated 代表该类启用参数验证,通过添加注解可以验证参数 * Created by bekey on 2017/12/20. */@RestController@RequestMapping("/user")@Validatedpublic class SysUserController {    //...}

    现在还不急着实现控制层,因为我们先要约定前后端交互的格式,下面是一个简易的格式 ,code是状态码200代表正常,message是消息通常应该是简单的一句话,data是额外的内容

消息格式及生成大量参考了 的代码,在此表示感谢

{    "code":200,    "message":"附带的消息",    "data":{}}

    为此,在entity下创建class RestResult 和 enum ResultCode 约定消息格式及状态码,因为RestResult十分常用,设置却比较麻烦,为防止错误返回,建议采用工厂模式生成,所以要在utils下添加一个生成类ResultGenerator 相关代码参阅 entity/RestResult  entity/ResultCode  utils/ResultGenerator

    好啦,这些搭完终于可以写controller了 /(ㄒoㄒ)/~~ java啰嗦果然名不虚传

现在我们只提供两个接口 分别是 register/login ,但是要添加参数验证

/**     * 匹配 /user/register 地址     * .在实体前添加 @Valid 注解代表要对这个实体进行验证,如果验证不通过就会报异常     * bindingResult是对异常信息的包装,不过这里我们不用,而是交由异常处理器进行处理     * @return 注册成功会将注册信息返回(!因为是demo所以没有考虑安全性)     */    @RequestMapping("/register")    public RestResult register(@Valid SysUser user, BindingResult bindingResult) {        return generator.getSuccessResult("用户注册成功",userService.saveUser(user));    }    /**     * 匹配 /user/login 地址 ,限定POST方法     * 。@NotNull 在字段前添加注解代表验证该字段,如果为空则报异常     * @return 登陆成功则返回相关信息,否则返回错误提示     */    @RequestMapping(value = "/login",method = RequestMethod.POST)    public RestResult login(@NotNull(message = "用户名不能为空") String name,@NotNull(message = "密码不能为空") String password, HttpSession session) {        SysUser user = userService.checkLogin(name, password);        if(user != null) {                //储存到session中            session.setAttribute("user",user);            return generator.getSuccessResult("登陆成功",user);        }        return generator.getFailResult("用户名/密码错误");    }

    这样我们的接口就写好了,但是如果参数没通过验证怎么办呢?程序报异常但是用户却得不到反馈是明显不可以的,所以我们添加一个exceptionHandler

/**     * 为参数验证添加异常处理器     */    @ExceptionHandler(ConstraintViolationException.class)    public RestResult handleConstraintViolationException(ConstraintViolationException cve) {        //这里简化处理了,cve.getConstraintViolations 会得到所有错误信息的迭代,可以酌情处理        String errorMessage = cve.getConstraintViolations().iterator().next().getMessage();        return generator.getFailResult(errorMessage);    }

    完整版代码请参阅 controller/SysUserController

    项目跑一下,访问localhost:8888 ... 嗯 404 我们没有主页,那在resources/static 下创建一个index.html,将就一下

    
这是主页

这是主页

    ok 在缺省配置下,框架会自动找到static下index.html 作为主页的 访问

    看是不是返回一个json,告诉你注册成功了呢?

{"code":200,"message":"用户注册成功","data":{"id":1,"name":"myadmin","password":"123456"}}

    好,那再访问一次

    看是不是返回一个json,告诉你密码应设为6至18位了呢?

{"code":400,"message":"密码应设为6至18位","data":null}

    再来一次

    看是不是返回一个json,告诉你违反主键/唯一约束条件了呢?

    试着登陆一下

    应该是一个404,因为只接受post请求,如果要验证可以通过其它方法

配置还没有结束 因为前后端分离,为了开发的方便,我们需要配置一下跨域,关于跨域问题,不理解的话可以去查阅一下资料 在config下新建一个CorsConfig

/** * 设置允许跨域 */@Configurationpublic class CorsConfig {    /**     允许任何域名使用       允许任何头       允许任何方法(post、get等)     */    private CorsConfiguration buildConfig() {        CorsConfiguration corsConfiguration = new CorsConfiguration();        corsConfiguration.addAllowedOrigin("*"); // 1        corsConfiguration.addAllowedHeader("*"); // 2        corsConfiguration.addAllowedMethod("*"); // 3        return corsConfiguration;    }    @Bean    public CorsFilter corsFilter() {        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();        source.registerCorsConfiguration("/**", buildConfig());         return new CorsFilter(source);    }}

    服务端的工作基本就完成大部分了,目前我们仅创建了两个接口,和一个临时主页,稍后完成前端项目之后才能继续。

    完整体源码 ->

前端项目搭建

后续内容

项目展示及源码

  • 服务端代码
  • 前端项目代码

服务端代码Github上创建了新的分支dev,整合了认证框架Security,并自定义Filter实现动态权限控制,有空的时候会分享一下个人体会

以后可能完善,谢谢。

转载于:https://my.oschina.net/u/3491123/blog/1592935

你可能感兴趣的文章
C++ 数字转换为string类型
查看>>
程序员全国不同地区,微信(面试 招聘)群。
查看>>
【干货】界面控件DevExtreme视频教程大汇总!
查看>>
闭包 !if(){}.call()
查看>>
python MySQLdb安装和使用
查看>>
Java小细节
查看>>
poj - 1860 Currency Exchange
查看>>
chgrp命令
查看>>
Java集合框架GS Collections具体解释
查看>>
洛谷 P2486 BZOJ 2243 [SDOI2011]染色
查看>>
linux 笔记本的温度提示
查看>>
(转)DOTA新版地图6.78发布:大幅改动 增两位新英雄
查看>>
工欲善其事必先利其器SecureCRT+VMware® Workstation_学习笔记
查看>>
文件和目录权限chmod,更改所有者和所属组chown,umask,隐藏权限lsattr/chattr
查看>>
阿里PB级Kubernetes日志平台建设实践
查看>>
怎么把无线由器限
查看>>
Java实现的冒泡排序
查看>>
APP中的第三方“支付”功能该如何测试
查看>>
HDU 1907
查看>>
数值积分中的辛普森方法及其误差估计
查看>>