前端指定返回字段解决方案

一,业务场景

个别场景中需要前端指定返回字段解决方案。必须一些可以编辑显示列的table,在这讨论几种实现方式。思路如下:

1,后端数据全返回,前端控制显示与否,缺点是增加数据库查询压力(都查出来了),增加流量传输。

2,数据库查询所有字段业务层序列化的时候指定序列化的字段,缺点就是增加数据库查询压力。

3,数据库动态查询,缺点是安全性健壮性不好把控(不可使用预先编译且有sql注入风险)。

仁者见仁智者见智,有没有更优秀,更优雅的方法欢迎谈论。

二,实现

第一种不用说,后端和往常一样,该怎么样还怎么样。

下面说后两种。

JSON序列化之指定序列化字段(fastjson,gson,jackson)

1,jackson

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.springframework.util.StringUtils;

/**
 * jackson自定义JSON返回字段
 *
 * @author Mr_Lee
 * @date 2020-08-13 08:35
 */
public class JackSonFilter {

    private static final String INCLUDE = "JSON_INCLUDE";
    private static final String EXCEPT = "JSON_EXCEPT";

    @JsonFilter(INCLUDE)
    private interface MyJsonInclude {
    }

    @JsonFilter(EXCEPT)
    private interface MyJsonExcept {
    }

    /**
     * 引入字段
     */
    public static String mapperInclude(Object bean, String include) throws JsonProcessingException {

        ObjectMapper mapper = new ObjectMapper();

        if (StringUtils.hasText(include)) {
            mapper.setFilterProvider(new SimpleFilterProvider().addFilter(INCLUDE,
                    SimpleBeanPropertyFilter.filterOutAllExcept(include.split(","))));

            mapper.addMixIn(bean.getClass(), MyJsonInclude.class);
        }

        return mapper.writeValueAsString(bean);
    }

    /**
     * 排除字段
     */
    public static String mapperExcept(Object bean, String except) throws JsonProcessingException {

        ObjectMapper mapper = new ObjectMapper();

        if (StringUtils.hasText(except)) {
            mapper.setFilterProvider(new SimpleFilterProvider().addFilter(EXCEPT,
                    SimpleBeanPropertyFilter.serializeAllExcept(except.split(","))));

            mapper.addMixIn(bean.getClass(), MyJsonExcept.class);
        }

        return mapper.writeValueAsString(bean);
    }
}

2,gson

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.util.StringUtils;

import java.util.Arrays;

/**
 * Gson自定义JSON返回字段
 *
 * @author Mr_Lee
 * @date 2020-08-13 10:04
 */
public class GsonFilter {

    /**
     * 引入字段
     */
    public static String toIncludeJson(Object bean, String include) {

        ExclusionStrategy myExclusionStrategy = new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes fa) {

                if (StringUtils.hasText(include)) {
                    return !Arrays.asList(include.split(",")).contains(fa.getName());
                }

                return true;
            }

            @Override
            public boolean shouldSkipClass(Class clazz) {
                return false;
            }
        };

        Gson gson = new GsonBuilder().setExclusionStrategies(myExclusionStrategy).create();
        return gson.toJson(bean);
    }

    /**
     * 排除字段
     */
    public static String toExceptJson(Object bean, String except) {

        ExclusionStrategy myExclusionStrategy = new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes fa) {

                if (StringUtils.hasText(except)) {
                    return Arrays.asList(except.split(",")).contains(fa.getName());
                }

                return false;
            }

            @Override
            public boolean shouldSkipClass(Class clazz) {
                return false;
            }
        };

        Gson gson = new GsonBuilder().setExclusionStrategies(myExclusionStrategy).create();
        return gson.toJson(bean);
    }
}

3,fastjson

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import org.springframework.util.StringUtils;

import java.util.Arrays;

/**
 * FastJson自定义JSON返回字段
 *
 * @author Mr_Lee
 * @date 2020-08-13 09:57
 */
public class FastJsonFilter {

    /**
     * 引入字段
     */
    public static String toIncludeJSONString(Object bean, String include) {
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();

        if (StringUtils.hasText(include)) {
            filter.getIncludes().addAll(Arrays.asList(include.split(",")));
        }

        return JSONObject.toJSONString(bean, filter);
    }

    /**
     * 排除字段
     */
    public static String toExceptJSONString(Object bean, String except) {
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();

        if (StringUtils.hasText(except)) {
            filter.getExcludes().addAll(Arrays.asList(except.split(",")));
        }

        return JSONObject.toJSONString(bean, filter);
    }
}

测试

import com.fasterxml.jackson.core.JsonProcessingException;

/**
 * @author Mr_Lee
 * @date 2020-08-13 08:37
 */
public class TestCase {

    public static void main(String[] args) throws JsonProcessingException {

        User user = new User(1, "lwc", "123456", true, "[email protected]");

        String jackSonString1 = JackSonFilter.mapperInclude(user, "id,userName");
        String jackSonString2 = JackSonFilter.mapperExcept(user, "id");
        System.out.println(jackSonString1);
        System.out.println(jackSonString2);

        System.out.println("---------------------------------------------");

        String fastJsonString1 = FastJsonFilter.toIncludeJSONString(user, "id,userName");
        String fastJsonString2 = FastJsonFilter.toExceptJSONString(user, "id");
        System.out.println(fastJsonString1);
        System.out.println(fastJsonString2);


        System.out.println("---------------------------------------------");

        String gsonString1 = GsonFilter.toIncludeJson(user, "id,userName");
        String gsonString2 = GsonFilter.toExceptJson(user, "id");
        System.out.println(gsonString1);
        System.out.println(gsonString2);
    }


}

{"id":1,"userName":"lwc"}
{"userName":"lwc","passWord":"123456","status":true,"email":"[email protected]"}
---------------------------------------------
{"id":1,"userName":"lwc"}
{"email":"[email protected]","passWord":"123456","status":true,"userName":"lwc"}
---------------------------------------------
{"id":1,"userName":"lwc"}
{"userName":"lwc","passWord":"123456","status":true,"email":"[email protected]"}

通过上面的方法可以实现方法二。

方法三呢?

可用MyBatis的动态SQL进行数据返回;故可在业务层将指定返回的列传入数据层,利用foreach标签进行遍历返回数据。

1.请求参数

@Data
public class QueryDTO {

    /**
     * 返回值
     */
    private Set targetFields;
}

2.mapper接口

	/**
     * 查询数据
     * @param record
     * @return
     */
    List query(QueryDTO record);

3.mapper.xml实现

  
    resourceId, platformCount, createUserId
  

  

4.注意事项
a.使用动态返回字段时,不可使用预先编译,故foreach中使用‘$’符号,而不使用‘#’;
b.foreach标签后若还有其他固定字段返回,记得用逗号‘,’分隔。

你可能感兴趣的:(tool)