背景:相信很多处于成长阶段的小伙伴都遇到过前端传参数后端接收不到,或者抱怨为什么后端需要一部分携带在url后面另外一部分放在body体内
说明:此文只针对前端跟后端Java(springboot)对接参数的情况
首先我们来看页面需求
我们常见的就是带有搜索条件查询,一般来说被搜索的字段直接是数据库对应字段对应还好说,但是像时间这种参数,一个字段对应的是两个值,跟数据库表实体类严重不匹配,这种情况,或者说比如状态这种字段为多选,就需要我们传一个数组给后端,也是跟实体类严重不匹配的情况
针对上面这种常见的情况我们应该如何优雅的传参数和接收参数呢,下面我们先从后端Java代码说起
一、springboot后端代码
建一个BaseEntity里面封装了createTime、updateTime、createBy、remark等常用字段,还有两个最重要的字段String
searchValue和 Mapparams属性,然后数据库表对应的实体类去继承这个基础类
很显然searchValue是为了接收跟数据库字段不匹配的基本类型的值,params是为了接收基本类型外的数据的例如 list map 等
package com.market.common.core.domain;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* Entity基类
*/
public class BaseEntity implements Serializable
{
private static final long serialVersionUID = 1L;
/** 搜索值 */
private String searchValue;
/** 创建者 */
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/** 备注 */
private String remark;
/** 请求参数 */
private Map<String, Object> params;
public String getSearchValue()
{
return searchValue;
}
public void setSearchValue(String searchValue)
{
this.searchValue = searchValue;
}
public String getCreateBy()
{
return createBy;
}
public void setCreateBy(String createBy)
{
this.createBy = createBy;
}
public Date getCreateTime()
{
return createTime;
}
public void setCreateTime(Date createTime)
{
this.createTime = createTime;
}
public String getUpdateBy()
{
return updateBy;
}
public void setUpdateBy(String updateBy)
{
this.updateBy = updateBy;
}
public Date getUpdateTime()
{
return updateTime;
}
public void setUpdateTime(Date updateTime)
{
this.updateTime = updateTime;
}
public String getRemark()
{
return remark;
}
public void setRemark(String remark)
{
this.remark = remark;
}
public Map<String, Object> getParams()
{
if (params == null)
{
params = new HashMap<>();
}
return params;
}
public void setParams(Map<String, Object> params)
{
this.params = params;
}
}
mapper.xml文件中则可以使用params.xxxx来访问这些参数
二、前端代码部分
前端因为是弱类型语言,我们可以把发送分成三种情况
因为我们在请求时可以封装自己的钩子函数handleArrayParams和tansParams
/**
*把数组处理成以,分割的字符串
* @param {*} params
* @returns
*/
export function handleArrayParams(params) {
let res = false;
if (params instanceof Object) {
Object.keys(params).forEach(key => {
if (Array.isArray(params[key])) {
params[key] = params[key].join(",")
}
})
}
return params;
}
handleArrayParams有什么作用呢,他可以把[1,2,3]这种数组格式的数据处理成1,2,3这种,后端就可以用List接收到
我们来看下效果
/**
* 参数处理
* @param {*} params 参数
*/
export function tansParams(params) {
let result = ''
for (const propName of Object.keys(params)) {
const value = params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && value !== "" && typeof (value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
result += subPart + encodeURIComponent(value[key]) + "&";
}
}
} else {
result += part + encodeURIComponent(value) + "&";
}
}
}
return result
}
tansParams可以把{params:{startTime:“2222”,endTime:“3333”}}转化成{params[startTime]:“2222”,params[endTime]:“3333”}这种格式,后端就可以使用map来接收,
最后我们看下效果