spring boot + Vue + iView前后端分离架构(Mac版) -- (五)前后端交互

spring boot + Vue + iView前后端分离架构(Mac版) – (五)前后端交互

小景哥哥博客

一、使用axios实现跨域请求

在前端项目hep-admin-web中的 src下创建lib目录,该目录主要用于存放axios封装的实现,并创建axios.jsapi.request.js文件。

axios.js

import Axios from 'axios';
import {Message} from 'iview';

class httpRequest {

    constructor() {
        this.options = {
            method: '',
            url: ''
        };
        // 存储请求队列
        this.queue = {};
    }

    // 销毁请求实例
    destroy(url) {
        delete this.queue[url];
        const queue = Object.keys(this.queue);
        return queue.length;
    }

    // 请求拦截
    interceptors(instance, url) {
        // 添加请求拦截器
        instance.interceptors.request.use(config => {
            // 在往后端发送请求的时候,还没有发送之前的处理,
            // 比如我们需要往我们的请求的header里面添加一些token或者其他信息的时候可以在此处进行相应的操作处理
            console.log('请求拦截')
            return config
        }, error => {
            // 对请求错误做些什么
            return Promise.reject(error);
        })

        // 添加响应拦截器
        instance.interceptors.response.use((res) => {
            // 已经完成了和后端的交互,此处已经获取到了后端返回的请求了,
            // 可以在此处做权限的验证拦截,比如用户非法登录的时候可以在此处重定向到登录页面
            let {data} = res;
            console.log('响应拦截'+res)
            return data;
        }, (error) => {
            Message.error('服务内部错误');
            // 对响应错误做点什么
            return Promise.reject(error);
        })
    }

    // 创建实例
    create() {
        let conf = {
            // 远程请求的服务的地址
            baseURL: "http://127.0.0.1:80",
            // 超时时间
            timeout: 5000,
            headers: {
                // 设置前端的跨域
                'Access-Control-Allow-Origin': '*',
                // 数据的提交方式为form的方式提交,若需要使用json的模式提交则将Content-Type值改为如下
                // application/json; charset=utf-8
                'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
                'X-URL-PATH': location.pathname
            }
        };
        return Axios.create(conf);
    }

    // 请求实例
    request(options) {
        let instance = this.create();
        this.interceptors(instance, options.url);
        options = Object.assign({}, options);
        this.queue[options.url] = instance;
        return instance(options);
    }
}
export default httpRequest;

api.request.js

import HttpRequest from './axios';
const axios = new HttpRequest();
export default axios;

二、后端项目访问接口实现

在后端项目的UserController中增加UserLoing方法接口。设置账户admin/123456默认可以登录,其余都拦截。

package com.huerpu.admin.web.core.controller;


import com.huerpu.admin.web.core.entity.User;
import com.huerpu.admin.web.core.service.UserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @ApiOperation(value = "Save Hep user")
    @PostMapping("save")
    public void getUserLists(User user){
        userService.save(user);
    }


    @ApiOperation("User Login")
    @PostMapping("login")
    public User UserLoing(@RequestParam(name = "loginAccount") String loginAccount, 
    @RequestParam(name = "loginPassword") String loginPassword){
        User user = new User();
        user.setUser_password(loginPassword);
        user.setUser_name(loginAccount);
        if("admin".equals(loginAccount) && "123456".equals(loginPassword)){
            user.setRoleResult("haveRole");
        }else{
            user.setRoleResult("noRole");
        }
        System.out.println(user);
        return user;
    }
}

entity目录中的User类中,设置一个字段roleResult用于判断是否有权限,其值设置为haveRole则有权限登录。

    /**
     * 用户登录返回值,haveRole证明登录成功
    */
    private String roleResult;

    public String getRoleResult() {
        return roleResult;
    }
    public void setRoleResult(String roleResult) {
        this.roleResult = roleResult;
    }

为了设置允许跨域访问,在controller同级目录下,创建一个config目录,在config目录创建CorsConfig.java文件。

package com.huerpu.admin.web.core.controller.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedHeaders("*")
                        .allowedMethods("*")
                        .allowedOrigins("*");
            }
        };
    }
}

三、前后端交互 – 前端实现

在前端项目hep-admin-websrc-->api目录下创建base.js,在src-->api-->sys-->user目录下创建user.api.js

base.js中涵盖一个通用的远程服务调用类。user.api.js用于和后端项目交互。

base.js

import axios from '../lib/api.request';
import qs from 'qs';

// 通用的远程访问的方法
export function fetch(url, params = {}) {
    return axios.request({
        // 响应的后端的接口的地址,不包含http://127.0.0.1:80这一部分,因此这一部分我们已经在axios.js中配置了
        url: url,
        // 由于我们的数据的提交方式是form的方式提交,因此需要对入参建转换
        data:qs.stringify(params),
        // 数据请求的方式为post
        method: 'post'
    });
}

user.api.js

import {fetch} from '../../base';

// 实现用户登录
export const login = params => {
    // /user/login这个就是后台的controller方法里的响应的地址,params就是我们的入参
    return fetch('/user/login',params);
};

修改login.vue文件,在loginSystem中认证登录,也就是后端传过来的User类中的roleResult字段,当其为haveRole时,即可登录放行,否则显示登录密码错误。

login.vue

<template>
  <div class="layout">
    <Layout>
      <Header class="layout-header" id="layout-header-scroll">
        <Menu mode="horizontal" theme="dark" active-name="1">
          <div class="layout-logo">
            <img height="50px" width="50px" src="../../assets/logo.png"/>
          </div>
          <div class="layout-nav">
            <language @on-lang-change="setLanguage" style="margin-right: 10px;" :lang="local"/>
          </div>
          <div class="layout-nav">
            <MenuItem name="1" style="font-size: 30px;">
              欢迎使用沪尔浦后台管理系统
            </MenuItem>
          </div>
        </Menu>
      </Header>
      <Content :style="{ background: '#fff', minHeight: '500px'}">
        <div style="float: right;margin: 100px 100px 0">
          <Card title="欢迎登录沪尔浦后台管理系统">
            <Form ref="loginForm" :model="loginForm" :rules="loginFormRule">
              <div>
                <FormItem prop="loginAccount">
                  账号:<Input v-model="loginForm.loginAccount" prefix="ios-contact"
                            :placeholder="$t('login.loginAccount')"
                            style="width: 200px;"/>
                </FormItem>
                <FormItem prop="loginPassword">
                  密码:<Input v-model="loginForm.loginPassword" prefix="ios-compass" type="password"
                            :placeholder="$t('login.loginPassword')" style="width: 200px;"/>
                </FormItem>
              </div>
            </Form>
            <div style="margin-top: 20px;">
              <Button type="primary" @click="loginSystem" :long=true>登录</Button>
            </div>
          </Card>
        </div>
      </Content>
    </Layout>
  </div>
</template>
<script>
  import Language from '../../components/language';
  import { login } from '../../api/sys/user/user.api';

  export default {
    components: {
      Language
    },
    data() {
      return {
        local: localStorage.getItem("lang"),
        loginForm: {
          loginAccount: '',
          loginPassword: ''
        },
        loginFormRule: {
          loginAccount: [
            {required: true, message: '请输入账号', trigger: 'blur'},
            {type: 'string', max: 30, message: '账号允许输入最大长度为30个字符', trigger: 'blur'}
          ],
          loginPassword: [
            {required: true, message: '请输入密码', trigger: 'blur'},
            {type: 'string', max: 50, message: '密码允许输入最大长度为50个字符', trigger: 'blur'}
          ]
        }
      }
    },
    methods: {
      loginSystem() {
        this.$refs['loginForm'].validate((valid) => {
          if (valid) {
            login(this.loginForm).then(res=>{
              console.info(res);
              if(res.roleResult=='haveRole'){
                this.$router.push({
                  name: 'main'
                })
              }else{
                this.$Message.error('账号密码错误!');
              }
            })

          }
        })
      },
      setLanguage(lang) {
        this.local = lang
        localStorage.setItem('lang', lang)
      }
    },
    mounted() {
    }
  }
</script>
<style scoped>

  .layout-header {
    position: relative;
    z-index: 999;
    height: 60px;
  }

  .layout {
    border: 1px solid #d7dde4;
    background: #f5f7f9;
    position: relative;
    border-radius: 4px;
    overflow: hidden;
  }

  .layout-nav {
    width: auto;
    float: right;
    margin: 0 auto;
    margin-right: 20px;
  }

  .layout-logo {
    width: 100px;
    height: 30px;
    border-radius: 10px;
    float: left;
    position: relative;
    left: 20px;
    top: 5px;
  }
</style>

四、启动前端项目、后端项目验证。

前端、后端项目目录结构如下:
在这里插入图片描述

在这里插入图片描述
访问登录页面http://127.0.0.1:8080/#/login,验证只有admin/123456可以登录,其余账户均显示密码错误,没有登录跳转。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勤奋的凯尔森同学

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值