MVC & MVVM学习 &VUE学习 & springboot小型项目开发(续上一篇)

VUE前端编写

前面提到过前后端分离的意思是前后端之间通过 RESTful API 传递 JSON 数据进行交流。不同于 JSP 之类,后端是不涉及页面本身的内容的。

在开发的时候,前端用前端的服务器(Nginx),后端用后端的服务器(Tomcat),当我开发前端内容的时候,可以把前端的请求通过前端服务器转发给后端(称为反向代理),这样就能实时观察结果,并且不需要知道后端怎么实现,而只需要知道接口提供的功能,两边的开发人员就可以各司其职啦。

正向代理:常见的就是梯子。比如我要访问A,但我访问不了,B可以访问,我就先访问B,踩着B去访问A。这是一个主动的过程。

反向代理:比如我访问A,A无法处理我的请求,A将我的请求转发到B处理,B处理完成之后又发回给A,这个过程我只知道我访问了A,并不知道A还有一个访问B的过程。这是一个被动的过程。通常可以用于保护B服务器IP。

前端页面开发

Login.vue

首先我们开发登录页面组件,右键 src\components 文件夹,New -> Vue Component,命名为 Login,如果没有 Vue Component 这个选项,可以选择新建一个 File,命名为 Login.vue 即可。代码如下:

<template>
  <div>
      用户名:<input type="text" v-model="loginForm.username" placeholder="请输入用户名"/>
      <br><br>
      密码: <input type="password" v-model="loginForm.password" placeholder="请输入密码"/>
      <br><br>
      <button v-on:click="login">登录</button>
  </div>
</template>
<script>

  export default {
    name: 'Login',
    data () {
      return {
        loginForm: {
          username: '',
          password: ''
        },
        responseResult: []
      }
    },
    methods: {
      login () {
        this.$axios
          .post('/login', {
            username: this.loginForm.username,
            password: this.loginForm.password
          })
          .then(successResponse => {
            if (successResponse.data.code === 200) {
              this.$router.replace({path: '/index'})
            }
          })
          .catch(failResponse => {
          })
      }
    }
  }
</script>

<template> 标签中随便写了一个登录的界面, methods 中定义了登录按钮的点击方法,即向后端 /login 接口发送数据,获得成功的响应后,页面跳转到 /index。因为之前我们设置了默认的 URL,所以请求实际上发到了 http://localhost:8443/api/login。

AppIndex.vue

右键 src\components 文件夹,新建一个 directory,命名为 home,再在 home 下新建一个 Appindex.vue ,即首页组件,先随便写个 Hello World。

<template>
    <div>
      Hello World!
    </div>
</template>

<script>
  export default {
    name: 'AppIndex'
  }
</script>
<style scoped>
</style>


3.前端相关配置

设置反向代理

修改 src\main.js 代码如下:


import Vue from 'vue'
import App from './App'
import router from './router'
// 设置反向代理,前端请求默认发送到 http://localhost:8443/api
var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8443/api'
// 全局注册,之后可在其他组件中通过 this.$axios 发送数据
Vue.prototype.$axios = axios
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

因为使用了新的模块 axios,所以需要进入到项目文件夹中,执行 npm install --save axios,以安装这个模块。

配置页面路由

修改 src\router\index.js 代码如下:

import Vue from 'vue'
import Router from 'vue-router'
// 导入刚才编写的组件
import AppIndex from '@/components/home/AppIndex'
import Login from '@/components/Login'

Vue.use(Router)

export default new Router({
  routes: [
  // 下面都是固定的写法
    {
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/index',
      name: 'AppIndex',
      component: AppIndex
    }
  ]
})

跨域支持

为了让后端能够访问到前端的资源,需要配置跨域支持。

在 config\index.js 中,找到 proxyTable 位置,修改为以下内容:


    proxyTable: {
      '/api': {
        target: 'http://localhost:8443',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }







运行项目

执行 npm run dev,查看登录页面效果。


注意地址是 localhost:8080/#/login ,中间有这个 # 是因为 Vue 的路由使用了 Hash 模式,是单页面应用的经典用法,但连开发者本人都觉得不太好看,所以可以在路由配置中选择使用 History 模式,但会引发一些问题,需要在后端作出处理。


后端开发

User 类

在 Login.vue 中,前端发送数据的代码段为:


.post('/login', {
            username: this.loginForm.username,
            password: this.loginForm.password
          })
后端如何接收这个 JS 对象呢?我们很自然地想到在需要创建一个形式上一致的 Java 类。

打开我们的后端项目 library,首先在 src\main\java\com\example\library文件夹(就是你自己的 web 项目的包)下,新建一个 pojo 包(package),然后新建 User类,代码如下:


package com.example.library.pojo;

import lombok.Data;

@Data
public class User {
    int id;
    String username;
    String password;

//    public int getId() {
//        return id;
//    }
//
//    public void setId(int id) {
//        this.id = id;
//    }
//
//    public String getUsername() {
//        return username;
//    }
//
//    public void setUsername(String username) {
//        this.username = username;
//    }
//
//    public String getPassword() {
//        return password;
//    }
//
//    public void setPassword(String password) {
//        this.password = password;
//    }
}


Result 类

Result 类是为了构造 response,主要是响应码。新建 result 包,创建 Result 类,代码如下:

package com.example.library.result;
public class Result {
    //响应码
    private int code;

    public Result(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }

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

}

LoginController

Controller 是对响应进行处理的部分。这里我们设定账号是 admin,密码是 123456,分别与接收到的 User 类的 username 和 password 进行比较,根据结果返回不同的 Result,即不同的响应码。前端如果接收到成功的响应码(200),则跳转到 /index 页面。

在 library下新建 controller 包,新建 LoginController 类,代码如下:

package com.example.library.controller;


import com.example.library.result.Result;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import com.example.library.pojo.User;

import java.util.Objects;
@Controller
public class LoginController {
    @CrossOrigin
    @PostMapping(value = "api/login")
    @ResponseBody
    public Result login(@RequestBody User requestUser) {
        // 对 html 标签进行转义,防止 XSS 攻击
        String username = requestUser.getUsername();
        username = HtmlUtils.htmlEscape(username);

        if (!Objects.equals("admin", username) || !Objects.equals("123456", requestUser.getPassword())){
            String message = "账号密码错误";
            System.out.println("test");
            return new Result(400);
        } else {
            return new Result(200);
        }
    }
}


这里只是为了演示前后端的交互过程,真正的登录验证要考虑更多因素,后面文章会持续更新。另外,实际上在 controller 里写这么多逻辑是不合理的,要尽量封装到 service 里面去。
最后,在 src\main\resources 文件夹下找到 application.yml文件配置端口,即加上 server.port=8443。

测试项目

同时运行前端和后端项目,访问 localhost:8080/#/login,输入用户名 admin,密码 123456

点击确定,成功进入 跳转到http://127.0.0.1:8080/#/index



最简陋的项目已经完成,后面继续更新数据库!


部分转载自:https://learner.blog.csdn.net/article/details/88955387


发表评论 / Comment

用心评论~