文章目录
- 流程图示
- 第一步:安装axios (前端)
- 第二步:创建utils/request.js文件
- 第三步:在main.js文件中配置axios
- 第四步:配置跨域解决方案filter (后端)
- 第五步:在页面传数据发请求 (前端)
- 第六步:编写Servlet (后端)
- 第七步:完善第五步中的请求
- 使用注解使password反序列化
流程图示
第一步:安装axios (前端)
第二步:创建utils/request.js文件
由于axios会自动转换JSON数据,那么前台post请求传给后台的数据就是json字符串,但是后台的getParameter..方法是根据key找value的,所以后台要求数据必须是键值对的方式,配置该文件可以实现前台传给后台的数据是键值对的方式
import axios from 'axios'
import qs from 'qs'
/**
* axios的传参方式:
* 1.url 传参 一般用于Get和Delete 实现方式:config.params={JSON}
* 2.body传参 实现方式:config.data = {JSON},且请求头为:headers: { 'Content-Type': 'application/json;charset=UTF-8' }
* 3.表单传参 实现方式:config.data = qs.stringify({JSON}),且请求头为:且请求头为:headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
*/
// axios实例
const $http = axios.create({
baseURL: 'http://localhost:8080/',
timeout: 60000,
headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
})
// 请求拦截器
$http.interceptors.request.use(
(config) => {
// 追加时间戳,防止GET请求缓存
if (config.method?.toUpperCase() === 'GET') {
config.params = { ...config.params, t: new Date().getTime() }
}
if (Object.values(config.headers).includes('application/x-www-form-urlencoded')) {
config.data = qs.stringify(config.data)
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
$http.interceptors.response.use(
response => {
const res = response.data
return res
},
error => {
return Promise.reject(error)
}
)
// cros 跨域是否允许凭证
$http.defaults.withCredentials = true;
// 导出 axios 实例
export default $http
第三步:在main.js文件中配置axios
下载了axios必须得导入引用才可以使用,注意一点:必须全部写在挂载函数mount()之前
这里$http为reque.js中暴露出来的
第四步:配置跨域解决方案filter (后端)
对所有的网址进行拦截,设置好跨域请求后再释放
@WebFilter(filterName = "AllFilter",urlPatterns = "/*")
public class AllFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
// response.setHeader("Access-Control-Allow-Origin", "*"); //允许所有的域名访问
// 允许携带cookie
response.setHeader("Access-Control-Allow-Origin",request.getHeader("origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, PATCH, DELETE"); //允许的提交方式
response.setHeader("Access-Control-Max-Age", "3600"); //最大有效时间
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type, Accept, Origin"); //允许那些请求头
response.setHeader("Access-Control-Allow-Credentials", "true"); //是否支持ajax提交cookie
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
第五步:在页面传数据发请求 (前端)
如果是get请求那么请求参数是通过url传递的 也就是
this.$axios.get("https://localhost:8080/login?user="+this.user+"&&password="+this.password).then(...)
如果是post请求那么请求参数通过对象的方式传递
第六步:编写Servlet (后端)
匹配请求的网址,对请求作出相应的操作,需要用到请求码和消息所以会封装几个类,实现响应给前台数据的一致,便于前台拿数据
Servlet:
使用JSON对象必须添加fastjson的jar包到lib目录下
@WebServlet(name = "LoginServlet2",urlPatterns = "/login")
public class LoginServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// 注意 : 这里跟之前的不一样,需要改成json格式
response.setContentType("application/json;charset=UTF-8");
String user = request.getParameter("user");
String password = request.getParameter("password");
LoginService loginService = new LoginServiceImpl();
User user1 = loginService.logintoUser(user, password);
PrintWriter writer = response.getWriter();
String json="";
if (user1!=null){
//登录成功
ResponseData<User> responseData = ResponseDataUtil.buildOk(user1);
json = JSON.toJSONString(responseData);
}else{
json = JSON.toJSONString(ResponseDataUtil.buildOk(ResultEnums.LOGIN_FAIL));
}
writer.print(json);
// 刷新,用于大文件
writer.flush();
}
}
请求码的属性类
public class Meta {
private int status;
private String msg;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
各种请求码及信息的枚举类
public enum ResultEnums {
OK(200, "请求成功"),
CREATED(201, "创建成功"),
DELETED(204, "删除成功"),
UPDATED(205, "修改成功"),
BAD_REQUEST(400, "请求的地址不存在或者包含不支持的参数"),
UNAUTHORIZED(401,"未授权"),
FORBIDDEN(403,"被禁止访问"),
LOGIN_FAIL(414,"用户名或者密码错误"),
NOT_FOUND(404,"请求的资源不存在"),
UNPROCESABLE_ENTITY(422,"[POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误"),
INTERNAL_SERVER_ERROR(500,"内部错误");
private int status;
private String msg;
ResultEnums(int status, String msg) {
this.status = status;
this.msg = msg;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
响应数据类
package com.ww.web.VuePag;
import java.io.Serializable;
/**
* <p>Title: ${file_name}</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2020</p>
* <p>Company: www.baidudu.com</p>
*
* @author suke
* @version 1.0
* @date ${date}
*/
public class ResponseData<T> implements Serializable {
private Meta meta = new Meta();
private T data;
public ResponseData(int status, String msg, T data) {
this.meta.setStatus(status);
this.meta.setMsg(msg);
this.data = data;
}
public ResponseData(int status, String msg) {
this.meta.setStatus(status);
this.meta.setMsg(msg);
}
public ResponseData(ResultEnums resultEnums) {
this.meta.setStatus(resultEnums.getStatus());
this.meta.setMsg(resultEnums.getMsg());
}
public ResponseData(ResultEnums resultEnums, T data) {
this.meta.setStatus(resultEnums.getStatus());
this.meta.setMsg(resultEnums.getMsg());
this.data = data;
}
public ResponseData() {
}
public Meta getMeta() {
return this.meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
创建响应数据的工具类
/**
* 带实体的统一返回
* data 实体
* <T> 实体类型
*
*/
public class ResponseDataUtil {
public static ResponseData buildOk(String msg) {
return new ResponseData(ResultEnums.OK.getStatus(), msg);
}
public static <T> ResponseData buildOk(T data) {
return new ResponseData<T>(ResultEnums.OK, data);
}
public static <T> ResponseData<T> buildOk(String msg,T data) {
return new ResponseData(ResultEnums.OK.getStatus(), msg,data);
}
public static ResponseData buildOk(int status , String msg) {
return new ResponseData(status, msg);
}
public static <T> ResponseData buildOk(int status, String msg, T data) {
return new ResponseData<T>(status, msg, data);
}
public static ResponseData buildOk(ResultEnums resultEnums) {
return new ResponseData(resultEnums);
}
public static <T> ResponseData buildCreate(T data) {
return new ResponseData<T>(ResultEnums.CREATED, data);
}
public static <T> ResponseData buildDelete(T data) {
return new ResponseData<T>(ResultEnums.DELETED, data);
}
public static <T> ResponseData buildUpdate(T data) {
return new ResponseData<T>(ResultEnums.UPDATED, data);
}
}
第七步:完善第五步中的请求
对响应回来的数据作出后续操作
login() {
var that = this; // 因为then中的是箭头函数,箭头函数this指向window,所以需要在开始时获取并赋值
this.$axios.post('login', {
user: that.user,
password: that.password
})
.then(function (response) {
// 处理成功情况
console.log(response);
if (response.meta.status === 200) {
// 登录成功
// 将接收回来的对象存放到本地存储中
let admin = response.data;
localStorage.setItem("token", admin.username)
// 跳转页面
that.$router.push({
name: "index",
// 将参数带入index页面
query: {
username: admin.username
}
})
} else {
// 登录失败
alert(response.meta.msg);
}
})
.catch(function (error) {
// 处理错误情况 500
alert("服务器出错")
});
}