zoukankan      html  css  js  c++  java
  • 18.Spring-Cloud-Zuul之文件上传和容错与回退

    对于通过API网关调用文件上传服务来说,文件(1M以内)无须任何处理,即看正常上传。对于大文件(10M以上)上传。需要在上传路径上添加/zuul前缀。也可使用zuul.servlet-path自定义前缀。

    文件上传演示

      pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0"
    
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    
       <modelVersion>4.0.0</modelVersion>
    
       <groupId>2.spring-cloud-service-provide</groupId>
    
       <artifactId>service-provide</artifactId>
    
       <packaging>jar</packaging>
    
       <version>0.0.1-SNAPSHOT</version>
    
       <name>spring-cloud Maven Webapp</name>
    
       <url>http://maven.apache.org</url>
    
       <!--springboot采用1.5.x 对应springcloud版本为 Dalston -->
    
       <parent>
    
          <groupId>org.springframework.boot</groupId>
    
          <artifactId>spring-boot-starter-parent</artifactId>
    
          <version>1.5.2.RELEASE</version>
    
          <relativePath />
    
       </parent> 
    
    
    
    <properties>
    
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    
          <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    
          <java.version>1.8</java.version>
    
          <spring-cloud.version>Dalston.RELEASE</spring-cloud.version>
    
       </properties>
    
       <dependencies>
    
          <dependency>
    
             <groupId>org.springframework.boot</groupId>
    
             <artifactId>spring-boot-starter-web</artifactId>
    
          </dependency>
    
          <!-- freemarker -->
    
          <dependency>
    
             <groupId>org.springframework.boot</groupId>
    
             <artifactId>spring-boot-starter-freemarker</artifactId>
    
          </dependency>
    
          <dependency>
    
             <groupId>org.springframework.boot</groupId>
    
             <artifactId>spring-boot-starter-actuator</artifactId>
    
          </dependency>
    
    <dependency>
    
             <groupId>org.springframework.cloud</groupId>
    
             <artifactId>spring-cloud-starter</artifactId>
    
          </dependency> 
    
          <dependency>
    
             <groupId>org.springframework.cloud</groupId>
    
             <artifactId>spring-cloud-starter-eureka</artifactId>
    
          </dependency>
    
          <dependency>
    
             <groupId>org.springframework.boot</groupId>
    
             <artifactId>spring-boot-starter-test</artifactId>
    
             <scope>test</scope>
    
          </dependency>
    
          <!--fastjson -->
    
          <dependency>
    
             <groupId>com.alibaba</groupId>
    
             <artifactId>fastjson</artifactId>
    
             <version>1.1.15</version>
    
          </dependency>
    
       </dependencies>
    
    
    
    <dependencyManagement>
    
          <dependencies>
    
             <dependency>
    
                <groupId>org.springframework.cloud</groupId>
    
                <artifactId>spring-cloud-dependencies</artifactId>
    
                <version>${spring-cloud.version}</version>
    
                <type>pom</type>
    
                <scope>import</scope>
    
             </dependency>
    
          </dependencies>
    
       </dependencyManagement>
    
       <!-- 这样变成可执行的jar -->
    
       <build>
    
          <plugins>
    
             <plugin>
    
                <groupId>org.springframework.boot</groupId>
    
                <artifactId>spring-boot-maven-plugin</artifactId>
    
             </plugin>
    
          </plugins>
    
       </build>
    
    </project>


     启动类

    package com.niugang;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * 文件上传
     * @author niugang
     *
     */
    @SpringBootApplication
    @EnableDiscoveryClient
    @ComponentScan
    public class Application {
    public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
    }
     


    配置文件

    #指定微服务的名称后续在调用的时候只需要使用该名称就可以进行服务的访问
    spring.application.name=service-fileupload-v1
    server.port=8778
    #注册中心地址
    eureka.client.serviceUrl.defaultZone=http://testhost:8000/eureka/,http://testhost2:8001/eureka/
    #把客户端的检测检测交给actuator来完成
    eureka.client.healthcheck.enabled=true
    #配置freemaker
    #默认加载类路径下 templates文件夹下的页面
    #spring.freemarker.template-loader-path=
    spring.freemarker.cache=false
    spring.freemarker.charset=UTF-8
    spring.freemarker.check-template-location=true
    spring.freemarker.content-type=text/html
    spring.freemarker.expose-request-attributes=true
    spring.freemarker.expose-session-attributes=true
    spring.freemarker.request-context-attribute=request
    spring.freemarker.suffix=.html
    #配置文件上传大小
    spring.http.multipart.max-file-size=20Mb
    spring.http.multipart.max-request-size=100Mb
     


    controller

    package com.niugang.controller;
    import java.io.File;
    import java.io.IOException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.util.FileCopyUtils;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    @Controller
    public class UploadController {
    
    private final Logger logger = LoggerFactory.getLogger(UploadController.class);
    
         @RequestMapping(value = "/index")
          public  String  index() {
        return "index";
           }
    
    /**
    *
    * @return
    * @throws IOException 
    */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public String upload(MultipartFile  file) throws IOException {
    byte[] bytes = file.getBytes();
    //这样默认上传文件就放在当前  项目路径下
    File name = new File(file.getOriginalFilename());
    FileCopyUtils.copy(bytes, name);
    return name.getAbsolutePath();
    }
    }

    页面:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>文件上传</title>
    </head>
    <body>
     <h4>spring cloud zuul  文件上传</h4>
     <form method="POST" action="upload" enctype="multipart/form-data">
    
    
    <input type="file" name="file" /><br />
    <br /> <input type="submit" value="提交" />
    </form>
     
    </body>
    </html>
     


    1.输入:http://localhost:8777/v1/service-fileupload/index启动注册中心,文件上传微服务,api网关。

    上传小于1M的;

    文件上传成功

    上传大于1M的:

    文件上传失败

    修改文件上传路径

    大文件上传成功

    zuul容错回退

    在没有添加zull容错回退是,经常可能因为请求转发报超时。

    1.其中如果不添加回退可以调大请求转发超时时间如下:

    #API网关路由转发请求hystrixCommand执行超时时间,默认为1000 即1s

    #hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000

    2.添加回退

    为zuul添加回退,需要实现ZuulFallbackProvider接口。在实现类中,指定为那个微服务提供回退,并提供一个ClientHttpResponse作为回退响应。

    package com.niugang.fallback;
    
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.charset.Charset;
    
    
    import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.client.ClientHttpResponse;
    import org.springframework.stereotype.Component;
    /**
     * 
     * @author zuul降级处理
     *当路由发生故障时提供回退。
     */
    @Component
    public class HellServiceFallback implements   ZuulFallbackProvider {
    
    
    @Override
    public String getRoute() {
       //表明为那个微服务提供回退
    return "feign-consumer-v1";
    }
    
    
    @Override
    public ClientHttpResponse fallbackResponse() {
    
    return new  ClientHttpResponse() {
    
    @Override
    public HttpHeaders getHeaders() {
    //headers设定
    HttpHeaders httpHeaders = new HttpHeaders();
    MediaType mediaType = new MediaType("application","json",Charset.forName("UTF-8"));
    httpHeaders.setContentType(mediaType);
    return httpHeaders;
    }
    
                     
    
    @Override
    public InputStream getBody() throws IOException {
    return new ByteArrayInputStream("微服务连接超时,请重试".getBytes());
    }
    
    @Override
    public String getStatusText() throws IOException {
    //状态文本
    return this.getStatusCode().getReasonPhrase();
    }
    
    @Override
    public HttpStatus getStatusCode() throws IOException {
    //fallback时的状态码
    return HttpStatus.OK;
    }
    
    @Override
    public int getRawStatusCode() throws IOException {
    //数字类型的状态码
    return this.getStatusCode().value();
    }
    
    @Override
    public void close() {
    
    }
    };
    }
    
    
    }

    配置以上,这样出错就会返回如下信息:

       

     微信公众号

     

     

  • 相关阅读:
    Effective Java 第三版——72. 赞成使用标准异常
    Effective Java 第三版——71. 避免不必要地使用检查异常
    Effective Java 第三版——70. 对可恢复条件使用检查异常,对编程错误使用运行时异常
    Effective Java 第三版——69. 仅在发生异常的条件下使用异常
    Effective Java 第三版——68. 遵守普遍接受的命名约定
    Effective Java 第三版——67. 明智谨慎地进行优化
    Effective Java 第三版——66. 明智谨慎地使用本地方法
    Effective Java 第三版——65. 接口优于反射
    Effective Java 第三版——64. 通过对象的接口引用对象
    Effective Java 第三版——63. 注意字符串连接的性能
  • 原文地址:https://www.cnblogs.com/niugang0920/p/12193032.html
Copyright © 2011-2022 走看看