文档章节

Spring MVC download

_冢彧
 _冢彧
发布于 2017/05/12 12:05
字数 1160
阅读 58
收藏 0
  • 前言

以前使用spring mvc做下载的时候大多数都是用电脑直接下载,所以没什么问题,现在接触一个需要用到手机的,结果只要一下载后台就报错,但是前端功能依旧,无任何异常。后来在问答中提出,经过 @tangqinchao 指点,在 https://my.oschina.net/songxinqiang/blog/891248 下面的博客找到了解决办法,MARK下来

  • 之前操作
  1. 之前下载代码
    @RequestMapping("info/download" + REQUEST_SUFFIX)
    @ResponseBody
    public String download(ModelMap modelMap, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
        doIt(null, modelMap, new ProcessImplementor<RequestBase>() {
            @Override
            public void process(RequestBase request, ModelMap response) {
                BufferedInputStream is = null;
                BufferedOutputStream os = null;
                try {

                    File file = new File(uploadBaseDir + "app/");
                    if (!file.exists() || ArrayUtils.isEmpty(file.list())) {
                        throw new LotteryException(ErrorCodeEnum.FILE_NOT_EXIST);
                    }
                    String name = Stream.of(file.list()).max(String::compareTo).get();

                    is = new BufferedInputStream(new FileInputStream(uploadBaseDir + "app/" + name));

//                    清空response
                    servletResponse.reset();
//                    设置response的Header
                    String userAgent = servletRequest.getHeader("User-Agent");
                    //针对IE或者以IE为内核的浏览器:
                    if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                        name = java.net.URLEncoder.encode(name, CharEncoding.UTF_8);
                    } else {
                        //非IE浏览器的处理:
                        name = new String(name.getBytes(CharEncoding.UTF_8), CharEncoding.ISO_8859_1);
                    }
                    servletResponse.setHeader("Content-Disposition", "attachment;filename=" + name);
                    servletResponse.setContentType("application/octet-stream");
                    servletResponse.setContentLength(is.available());
                    os = new BufferedOutputStream(servletResponse.getOutputStream());
                    IOUtils.copy(is, os);
                    os.flush();
                } catch (IOException e) {
                    throw new LotteryException(ErrorCodeEnum.FILE_DOWNLOAD_FAIL, e);
                } finally {
                    IOUtils.closeQuietly(is);
                    IOUtils.closeQuietly(os);
                }

            }
        });
        return WebUtil.ajaxJsonReturn(modelMap);
    }
  1. 之前报错日志
2017-05-11 16:34:07.329 ERROR [http-nio-8080-exec-5] IndexController:94- lottery ERROR={}
com.mzw.lottery.exception.LotteryException: 文件下载失败
        at com.mzw.lottery.web.controller.index.IndexController$7.process(IndexController.java:219)
        at com.mzw.lottery.common.base.ControllerBase.doIt(ControllerBase.java:60)
        at com.mzw.lottery.web.controller.index.IndexController.download(IndexController.java:186)
        at com.mzw.lottery.web.controller.index.IndexController$$FastClassBySpringCGLIB$$6531ceb0.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
        at com.mzw.lottery.web.controller.index.IndexController$$EnhancerBySpringCGLIB$$a92cf6c9.download(<generated>)
        at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:108)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
        at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356)
        at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:778)
        at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:707)
        at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:391)
        at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:369)
        at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
        at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:639)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.write(BufferedOutputStream.java:126)
        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2147)
        at org.apache.commons.io.IOUtils.copy(IOUtils.java:2102)
        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2123)
        at org.apache.commons.io.IOUtils.copy(IOUtils.java:2078)
        at com.mzw.lottery.web.controller.index.IndexController$7.process(IndexController.java:216)
        ... 113 common frames omitted
Caused by: java.io.IOException: Broken pipe
        at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
        at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
        at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
        at sun.nio.ch.IOUtil.write(IOUtil.java:65)
        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
        at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:134)
        at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101)
        at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157)
        at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1238)
        at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:670)
        at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:450)
        at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:388)
        at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:581)
        at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:118)
        at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:223)
        at org.apache.coyote.Response.doWrite(Response.java:517)
        at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351)
        ... 126 common frames omitted
2017-05-11 16:34:07.330 INFO  [http-nio-8080-exec-5] IndexController:70- No transaction aspect-managed TransactionStatus in scope
2017-05-11 16:34:07.330 INFO  [http-nio-8080-exec-5] IndexController:79- 执行结果lottery LOTTERY_STATUS=FAIL,LOTTERY_CODE=L010_03_0062,LOTTERY_MESSAGE=文件

 

  • 正确的下载姿势
    @RequestMapping("info/download" + REQUEST_SUFFIX)
    @ResponseBody
    public ResponseEntity<Resource> download(ModelMap modelMap, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
        doIt(null, modelMap, new ProcessImplementor<RequestBase>() {
            @Override
            public void process(RequestBase request, ModelMap response) {
                try {

                    Path p = Paths.get(uploadBaseDir + "app/");

                    if (null == p || !Files.exists(p)) {
                        throw new LotteryException(ErrorCodeEnum.FILE_NOT_EXIST);
                    }
                    p = Files.list(p).max((e1, e2) -> e1.getFileName().compareTo(e2.getFileName())).orElse(null);
                    if (null == p || !Files.exists(p)) {
                        throw new LotteryException(ErrorCodeEnum.FILE_NOT_EXIST);
                    }

                    File f = p.toFile();
                    String name = f.getName();

//                    设置response的Header
                    String userAgent = servletRequest.getHeader("User-Agent").toUpperCase();
                    //针对IE或者以IE为内核的浏览器:
                    if (userAgent.contains("MSIE") || userAgent.contains("TRIDENT") || userAgent.contains("EDGE")) {
                        name = java.net.URLEncoder.encode(name, CharEncoding.UTF_8);
                    } else {
                        //非IE浏览器的处理:
                        name = new String(name.getBytes(CharEncoding.UTF_8), CharEncoding.ISO_8859_1);
                    }

                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                    headers.setContentDispositionFormData("attachment", name);
                    headers.setContentLength(f.length());

                    response.addAttribute(Constants.DATA, new ResponseEntity<Resource>(new FileSystemResource(f), headers, HttpStatus.OK));
                } catch (IOException e) {
                    throw new LotteryException(ErrorCodeEnum.FILE_DOWNLOAD_FAIL, e);
                }
            }
        });
        return (ResponseEntity<Resource>) modelMap.get(Constants.DATA);
    }

 

  • 结语

感谢 @tangqinchao 的帮助

https://my.oschina.net/songxinqiang/blog/891248

© 著作权归作者所有

共有 人打赏支持
上一篇: Spring Boot HTTPS
下一篇: 札记
_冢彧
粉丝 6
博文 13
码字总数 11898
作品 0
渝北
程序员
私信 提问
Build Spring MVC development environment

Short memo for how to build Spring MVC develepmnet environment (for windows). In case you have any questions, please feel free to leave message to me under this article. I will ......

Marvin_Chen
06/26
0
0
fastupload-springmvc 0.5.5 发布

fastupload-springmvc是利用fastupload开源组件Spring MVC框架写的文件上传插件,使用此插件,能在Controller中以注解的方式来获取上传的文件,然后对其进行操作。比使用fastupload核心API更...

仪山湖
2013/04/15
1K
8
Spring Mobile 1.1.0.M3 发布

Spring Mobile 今天发布 1.1.0 的第三个里程碑版本。该版本基于 Spring Framework 3.2.2 进行测试,改进记录请看 changelog 和 reference manual 下载地址:http://www.springsource.com/dow...

红薯
2013/04/06
816
0
Spring Mobile 1.0 正式版发布

Spring Mobile 1.0 发布了,Spring Mobile 是 Spring MVC 框架的扩展用于跨平台的移动 Web 应用开发。 该 GA 版本包含对 RC2 的小bug修复和改动,想起请看 changelog 和 reference manual 以...

douglarek
2012/05/15
1K
3
Spring Web Flow 2.1 发布-下载

Spring Web Flow单元是一个MVC的扩展,它允许你使用一个高阶域定义语言来定义控制器。这个语言 用来建模用户交互,需要多次请求到服务器来完成,并可能涉及不同的内容。 Spring Web Flow 2....

红薯
2010/06/19
562
0

没有更多内容

加载失败,请刷新页面

加载更多

Sping之项目中pofile的应用

工程中,我们必须要面对的一件事就是, 开发环境中使用的数据库连接地址等与生产上的不同, 如果上线, 那么我们是否还要手动修改这些地址么, 这样做有很多弊端, 不方便, 这时我们就可以使用spr...

克虏伯
8分钟前
0
0
Linux中安装MySQL

Linux中安装MySQL 一、准备工作 此处准备的操作系统位CentOS 7。 MySQL安装包: MySQL-server-5.6.29-1.linux_glibc2.5.x86_64.rpm MySQL-client-5.6.29-1.linux_glibc2.5.x86_64.rpm 将准备......

星汉
13分钟前
0
0
深入理解Hadoop之HDFS架构

Hadoop分布式文件系统(HDFS)是一种分布式文件系统。它与现有的分布式文件系统有许多相似之处。但是,与其他分布式文件系统的差异是值得我们注意的: HDFS具有高度容错能力,旨在部署在低成...

架构师springboot
17分钟前
0
0
MaxCompute表设计最佳实践

MaxCompute表设计最佳实践 产生大量小文件的操作 MaxCompute表的小文件会影响存储和计算性能,因此我们先介绍下什么样的操作会产生大量小文件,从 而在做表设计的时候考虑避开此类操作。 使用...

阿里云官方博客
17分钟前
0
0
云上领跑,快人一步:华为云抢先发布Redis5.0

12月17日,华为云在DCS2.0的基础上,快人一步,抢先推出了新的Redis 5.0产品,这是一个崭新的突破。目前国内在缓存领域的发展普遍停留在Redis4.0阶段,华为云率先发布了Redis5.0,全面展现了...

中间件小哥
18分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部