json数组转js数组_数组转json_js json对象转json数组

1. 业务场景

业务前提是公司的项目有一个【广告】保存接口,现要把 ADX 将投放的广告数据存储在我们系统,方便后续的使用。

传输JSON数据结构示例:

{
    "adName":"",
    "adTag":""
}

所以传输JSON数据这么大的情况下,接口不优化的情况下,就带来了这几个弊端:

2. 方案设计

试想一下有什么办法可以解决这样的问题?

我们在请求方发起请求前先对数据进行压缩,然后再发起请求到我们系统的保存接口数组转json数组转json,当然在我们的接收接口后再保存到系统之前对请求数据进行解压,还原成 JSON 对象就完成了整个 压缩数据的请求以及处理流程。

实际上这种解决方案也是有弊端的,例如:

当然这些问题也不要担心,具体还是需要根据你们公司具体业务场景。我司业务场景为了解决这问题做了一点调整:

3. 方案实现前置知识:方案流程示例图:

js json对象转json数组_json数组转js数组_数组转json

源代码:

搭建一个SpringBoot项目(很简单,这里就不多聊了)。

Controller层编写一个保存广告数据的接口,参数只需要接收 JSON 对象即可。

/**
 * @ClassName: AdvertisementController
 * @Author hf
 * @Date 2022/3/29 20:41
 */
@Slf4j
@RestController
public class AdvertisementController {
    @PostMapping("/saveAdvertisement")
    public Advertising saveAdvertisement(@RequestBody Advertisement params) {
        log.info("接收到了请求内容:"+ params");
      return advertising;
    }
}

Dao实体

/**
 * @ClassName: Advertisement
 * @Author hf
 * @Date 2022/3/29 20:42
 */
@Data
public class Advertisement {
    private String adName;
    private String adTag;
}

自定义拦截器

/**
 * @ClassName: MyGZIPFilter
 * @Author hf
 * @Date 2022/3/29 21:00
 */
@Component
@Slf4j
public class MyGZIPFilter implements Filter {
    private static final String CONTENT_ENCODING = "Content-Encoding";
    private static final String CONTENT_ENCODING_TYPE = "gzip";
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("init MyGZIPFilter");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        StopWatch stopWatch = new StopWatch();//用来计算耗时,前面有章多种代码耗时统计总结,可以去翻一下
				stopWatch.start();//开始计时
      
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        String encodeType = httpServletRequest.getHeader(CONTENT_ENCODING);
        if (CONTENT_ENCODING_TYPE.equals(encodeType)) {
            log.info("请求:{} 需要解压", httpServletRequest.getRequestURI());
            UnZIPRequestWrapper unZIPRequestWrapper = new UnZIPRequestWrapper(httpServletRequest);
            filterChain.doFilter(unZIPRequestWrapper,servletResponse);
        }else {
            log.info("请求:{} 无需解压", httpServletRequest.getRequestURI());
            filterChain.doFilter(servletRequest,servletResponse);
        }
      
      	stopWatch.stop();//结束计时
        log.info("耗时:{}ms", stopWatch.getTotalTimeMillis());
    }
    @Override
    public void destroy() {
        log.info("destroy GZIPFilter");
    }
}

注册自定义拦截器

/**
 * @ClassName: MyFilterRegistration
 * @Author hf
 * @Date 2022/3/29 21:20
 */
@Configuration
public class MyFilterRegistration {
    @Resource
    private MyGZIPFilter myGZIPFilter;
    @Bean
    public FilterRegistrationBean gzipFilterRegistrationBean() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        
        registration.setFilter(gzipFilter);//Filter可以new,也可以使用依赖注入Bean
        
        registration.setName("myGZIPFilter");//自定义过滤器名称
        
        registration.addUrlPatterns("/*");//拦截路径,我这里设置的所有
        
        registration.setOrder(1);//设置顺序
        return registration;
    }
}

RequestWrapper 实现请求数据解压,并将解压后的请求数据回写到 Body 中。

/**
 * @ClassName: UnZIPRequestWrapper
 * @Author hf
 * @Date 2022/3/29 21:30
 * @Description: JsonString请求数据压缩后保存为二进制文件 -> 解压缩后还原成JsonString转换成byte[] 回写body中
 */
@Slf4j
public class UnZIPRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] bytes;
    public UnZIPRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        try (BufferedInputStream bis = new BufferedInputStream(request.getInputStream());
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            final byte[] body;
            byte[] buffer = new byte[1024];
            int len;
               
            while ((len = bis.read(buffer)) > 0) {
                baos.write(buffer, 0, len);
            }
               
            body = baos.toByteArray();
               
            if (body.length == 0) {
                log.info("Body无内容,无需解压");
                bytes = body;
                return;
            }
               
            this.bytes = GZIPUtils.uncompressToByteArray(body);
               
        } catch (IOException ex) {
            log.info("GZIP解压缩异常!");
            ex.printStackTrace();
            throw ex;
        }
    }
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {
            }
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
}

最后就是编写我们的GZIP工具类了。

/**
 * @ClassName: MyGZIPUtils
 * @Author hf
 * @Date 2022/3/29 21:45
 */
public class MyGZIPUtils {
    public static final String GZIP_ENCODE_UTF_8 = "UTF-8";
		/**
     * GZIP解压缩
     * @param bytes
     * @return
     */
    public static byte[] uncompress(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        try {
            GZIPInputStream ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[256];
            int n;
            while ((n = ungzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }
    /**
     * GZIP解压并返回String
     * @param bytes
     * @return
     */
    public static String uncompressToString(byte[] bytes) throws IOException {
        return uncompressToString(bytes, GZIP_ENCODE_UTF_8);
    }
    /**
     * GZIP解压并返回字节数组
     * @param bytes
     * @return
     */
    public static byte[] uncompressToByteArray(byte[] bytes) throws IOException {
        return uncompressToByteArray(bytes, GZIP_ENCODE_UTF_8);
    }
    /**
     * GZIP解压成字符串并返回字符串
     * @param bytes 压缩后的字节数组
     * @param encoding 编码方式
     * @return 解压后的字符串
     */
    public static String uncompressToString(byte[] bytes, String encoding) throws IOException {
        byte[] result = uncompressToByteArray(bytes, encoding);
        return new String(result);
    }
    /**
     * GZIP解压成字节数组
     * @param bytes
     * @param encoding
     * @return
     */
    public static byte[] uncompressToByteArray(byte[] bytes, String encoding) throws IOException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        try {
            GZIPInputStream ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[256];
            int n;
            while ((n = ungzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            return out.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw new IOException("GZIP解压失败!");
        }
    }
    /**
     * 将字节流转换成文件
     * @param filename
     * @param data
     * @throws Exception
     */
    public static void saveFile(String filename,byte [] data)throws Exception{
        if(data != null){
            String filepath ="/" + filename;
            File file  = new File(filepath);
            if(file.exists()){
                file.delete();
            }
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data,0,data.length);
            fos.flush();
            fos.close();
            System.out.println(file);
        }
    }
    /**
     * 把字符串压缩为GZIP字节数组
     * @param str
     * @return
     */
    public static byte[] compress(String str) {
        return compress(str, GZIP_ENCODE_UTF_8);
    }
    /**
     * 把字符串压缩为GZIP字节数组
     * @param str
     * @param encoding
     * @return
     */
    public static byte[] compress(String str, String encoding) {
        if (str == null || str.length() == 0) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(str.getBytes(encoding));
            gzip.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }   

4. 结果测试

一定要注意这个坑:

千万千万不要直接把压缩后的 byte[] 用来传输,不信你试试会发现这样做比没压缩的强请求包还要大得多!

压缩后的 byte[]两种传输法:

接下来用 POSTMAN 测试一下 GZIP 压缩数据请求效果:

大家可以收藏一下,后续会持续更新更多的干货知识。

限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688