后端
1.创建一个springboot项目,具体过程我之前写过一篇博客,可以效仿。
idea创建springboot2+maven+springmvc项目
2.创建好目录
3.result中的3个类如下,用于通用的返回
Result
package com.csyd.result;
/**
* 统一API响应结果封装
*/
public class Result {
private int code;
private String message;
private Object data;
public Result setCode(ResultCode resultCode) {
this.code = resultCode.getCode();
return this;
}
public int getCode() {
return code;
}
public Result setCode(int code) {
this.code = code;
return this;
}
public String getMessage() {
return message;
}
public Result setMessage(String message) {
this.message = message;
return this;
}
public Object getData() {
return data;
}
public Result setData(Object data) {
this.data = data;
return this;
}
}
ResultCode
package com.csyd.result;
/**
* 响应码枚举,参考HTTP状态码的语义
*/
public enum ResultCode {
SUCCESS(200, "sucess"),//成功
FAIL(400, "失败"),//失败
;
private Integer code;
private String msg;
ResultCode(int code) {
this.code = code;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
ResultCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
}
ResultGenerator
package com.csyd.result;
/**
* 响应结果生成工具
*/
public class ResultGenerator {
private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
public static Result genSuccessResult() {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMessage(DEFAULT_SUCCESS_MESSAGE);
}
public static Result genSuccessResult(Object data) {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMessage(DEFAULT_SUCCESS_MESSAGE)
.setData(data);
}
public static Result genFailResult(String message) {
return new Result()
.setCode(ResultCode.FAIL)
.setMessage(message);
}
public static Result genFailResult(ResultCode resultCode) {
return new Result()
.setCode(resultCode.getCode())
.setMessage(resultCode.getMsg());
}
}
4.pofo.vo中的LoginVo,是作为登陆的实体类,可以进行校验,很方便
package com.csyd.pojo.vo;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
/**
* Created by ChengShanyunduo
* 2019/3/25
*/
public class LoginVo {
@NotNull(message="用户名不允许为空")
@Length(min=3,max=16,message="用户名长度不正确!")
private String username;
@NotNull(message="密码不允许为空")
@Length(min=6,max=16,message="密码长度不正确!")
private String password;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}
5.UserController中写接口,同时对Vo中的校验规则进行反馈,@Valid是进行校验,BindingResult中可以返回校验的结果,这里我用户名和密码是写死的,还有一个注解@CrossOrigin是用在跨域请求上的,因为这里做的是前后端分离,正常来说跨域的请求是会被阻拦的,所以这里我们就要进行一些配置。
package com.csyd.controller;
import com.csyd.pojo.vo.LoginVo;
import com.csyd.result.Result;
import com.csyd.result.ResultGenerator;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.Valid;
import java.util.Objects;
/**
* Created by ChengShanyunduo
* 2019/3/25
*/
@Controller
@RequestMapping("/api")
public class UserController {
@CrossOrigin //跨域请求必加
@RequestMapping("/user/login")
@ResponseBody
public Result login(@Valid @RequestBody LoginVo loginVo, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
String message = String.format("登陆失败,详细信息[%s]。", bindingResult.getFieldError().getDefaultMessage());
return ResultGenerator.genFailResult(message);
}
if (!Objects.equals("admin", loginVo.getUsername()) || !Objects.equals("123456", loginVo.getPassword())) {
String message = String.format("登陆失败,详细信息[用户名、密码信息不正确]。");
return ResultGenerator.genFailResult(message);
}
return ResultGenerator.genSuccessResult();
}
}
6.在刚才提到的跨域请求中,除了加注解以外,还要再config中加一个配置文件。这里我进行了具体的限制,如果开放所有的话,就把被注释掉的那里替换出来。
CORSConfig
package com.csyd.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;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import static sun.tools.jconsole.Messages.ALL;
/**
* Created by ChengShanyunduo
* axios跨域请求问题
* 2019/3/25
*/
@Configuration
public class CORSConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 限制了路径和域名的访问
registry.addMapping("/api*").allowedOrigins("http://localhost:8080");
// registry.addMapping("/**")
// .allowedOrigins(ALL)
// .allowedMethods(ALL)
// .allowedHeaders(ALL)
// .allowCredentials(true);
}
};
}
}
前端
1.前端页面,data中都是一些数据,ruleValidate中进行数据的校验,methods中放方法
Login.vue
<style>
html,body {
width: 100%;
height: 100%;
background: url("../assets/background.jpg");
}
.from-wrap{
width: 100%;
height: 260px;
border-radius: 10px;
background-color: #fff;
padding: 20px 30px;
margin-top: 60%;
}
h1 {
text-align: center;
margin-bottom: 20px;
}
FormItem {
margin-bottom: 30px;
}
.form-footer {
text-align: right;
}
</style>
<template>
<Row>
<Col :xs="{ span: 20, offset: 2 }" :md="{ span: 6, offset: 16 }">
<div class="from-wrap">
<h1>登录</h1>
<Form ref="loginVo" :model="loginVo" :rules="ruleValidate" >
<FormItem prop="username">
<Input type="text" v-model="loginVo.username" placeholder="请输入用户名">
<Icon type="ios-person-outline" slot="prepend"></Icon>
</Input>
</FormItem>
<FormItem prop="password">
<Input type="password" v-model="loginVo.password" placeholder="请输入密码">
<Icon type="ios-lock-outline" slot="prepend"></Icon>
</Input>
</FormItem>
<FormItem class="form-footer">
<Button type="primary" @click="handleSubmit()">Submit</Button>
</FormItem>
</Form>
</div>
</Col>
</Row>
</template>
<script>
export default {
data () {
return {
loginVo: {
username:'',
password:''
},
ruleValidate: {
username: [
{ required: true, message: '账号不能为空', trigger: 'blur' },
{ min: 3, max: 16, message: '账号长度3-16个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '密码不能为空', trigger: 'blur' },
{ type: 'string', min: 6, max: 16, message: '密码长度6-16个字符', trigger: 'blur' }
]
},
responseResult: []
}
},
methods: {
handleSubmit () {
this.$axios
.post('/user/login', {
username: this.loginVo.username,
password: this.loginVo.password
})
.then(successResponse => {
this.responseResult = JSON.stringify(successResponse.data);
if (successResponse.data.code === 200) {
this.$router.replace({path: '/manage/page1'})
}else {
alert(successResponse.data.message)
}
})
.catch(function (error) {
console.log(error);
});
}
}
}
</script>
2.同样这里也有跨域的问题,需要加一些东西。
首先,在config中index.js里 //Path中proxyTable里加一段
//添加这一段,跨域设置
'/api': {
target: 'http://localhost:8765',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
3.设置axios的请求。在main.js中加上一段,设置默认的请求路径。
// 引用axios,并设置基础URL为后端服务api地址
var axios = require('axios')
//设置默认请求路径
axios.defaults.baseURL = 'http://localhost:8765/api'
// 将API方法绑定到全局
Vue.prototype.$axios = axios