SpringCloud入门(九): Zuul 上传&回退&异常处理&跨域

Zuul的上传

1、构建一个上传类

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

@RestController
@RequestMapping("/file")
public class FileUploadController {

    @PostMapping(value = "/upload", consumes = "multipart/form-data")
    public Object upload(@RequestParam("file") MultipartFile file) throws IOException {
        File temp = new File("D:/" + file.getOriginalFilename());
        if(!temp.getParentFile().exists()){
            temp.getParentFile().mkdir();
        }
        try {
            file.transferTo(temp); //保存文件
            return Boolean.TRUE;
        } catch (IllegalStateException e) {
            e.printStackTrace();
            return Boolean.FALSE;
        } catch (IOException e) {
            e.printStackTrace();
            return Boolean.FALSE;
        }
    }
}

2、配置属性文件

zuul默认文件上传的时候,会走Spring DispatcherServlet,这个时候会对文件大小进行判断,默认为10M;如果要传大文件需要对文件大小进行设置。

zuul.ignored-services=*
zuul.routes.use-routing.serviceId=ms-provider-order
zuul.routes.use-routing.path=/order-service/**
zuul.routes.use-routing.sensitiveHeaders=

spring.servlet.multipart.max-file-size=4000MB
spring.servlet.multipart.max-request-size=4000MB

通过/zuul来访问,可以绕过DispatcherServlet转为zuulServlet,在上传大文件的时候不需要设置文件大小,但是需要设置hystrix和ribbon的超时时间。

zuul.ignored-services=*
zuul.routes.use-routing.serviceId=ms-provider-order
zuul.routes.use-routing.path=/order-service/**
zuul.routes.use-routing.sensitiveHeaders=

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=600000
ribbon.ConnectTimeout=100000
ribbon.ReadTimeout=100000

3、通过PostMan测试

zuul的回退

1、自定义一个回退类

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class CustomZuulFallBack implements FallbackProvider {
    @Override
    public String getRoute() {
        return "*"; //*表示为所有微服务提供回退
        //return "ms-provider-order"  //指定某个微服务回退
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.OK.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.OK.getReasonPhrase();
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("后端服务不可用".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                //和body中的内容编码一致,否则容易乱码
                headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                return headers;
            }
        };
    }
}

zuul的回退只支持宕机回退(服务挂了)和超时回退(服务请求超时)两种;

如果服务自己抛出的异常(404,500等),zuul的回退监控不到;原因就在于RibbonRoutingFilter的拦截器,在拦截器run中的forward方法,只争对了HystrixRuntimeException的拦截,500等异常会直接由SpringBoot的BasicErrorController接管抛出到页面;

protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception {
    Map<String, Object> info = this.helper.debug(context.getMethod(),
            context.getUri(), context.getHeaders(), context.getParams(),
            context.getRequestEntity());

    RibbonCommand command = this.ribbonCommandFactory.create(context);
    try {
        ClientHttpResponse response = command.execute();
        this.helper.appendDebug(info, response.getRawStatusCode(), response.getHeaders());
        return response;
    }
    catch (HystrixRuntimeException ex) {
        return handleException(info, ex);
    }
}

zuul的全局异常处理

1、自定义一个异常处理类

import com.alibaba.fastjson.JSON;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Component
public class CustomErrorFilter extends SendErrorFilter {

    @Override
    public Object run() {
        try {
            RequestContext ctx = RequestContext.getCurrentContext();
            ExceptionHolder exception = findZuulException(ctx.getThrowable());
            //HttpServletRequest request = ctx.getRequest();

            HttpServletResponse response = ctx.getResponse();
            response.setContentType("text/html; charset=UTF-8");
            response.setCharacterEncoding("UTF-8");

            Map<String,Object> errorMap = new HashMap<>();
            errorMap.put("code","203");
            errorMap.put("errMsg",exception.getThrowable().getCause().getMessage());

            response.getWriter().write(JSON.toJSONString(errorMap));
        }
        catch (Exception ex) {
            ReflectionUtils.rethrowRuntimeException(ex);
        }
        return null;
    }
}

2、禁用系统自带的异常处理类

zuul.SendErrorFilter.error.disable=true

zuul的跨域问题

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许cookies跨域
        config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
        config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
        config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
        config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

原文地址:https://www.cnblogs.com/jiangyaxiong1990/p/12649664.html

时间: 2024-10-15 04:06:40

SpringCloud入门(九): Zuul 上传&回退&异常处理&跨域的相关文章

form上传文件以及跨域异步上传

要设置了enctype属性才能上传,需要使用上传的jar包,这里使用的是cos-26Dec2008.jar, 而且后台获取值的时候,getfile要放在第一位 一次设置好上传格式后没有上传文件,也就没有getFile,结果总是取不到值,删掉enctype="multipart/form-data"属性就ok了. 关于跨域上传文件: 跨域上传文件总会报错,即使服务器端设置了header('Access-Control-Allow-Origin: *'),仍会报错说缺少multipart属

easy ui 异步上传文件,跨域

easy ui 跨域上传文件,代码如下: 1.html代码:(这段代码是个win窗体,我在点击上传图片按钮然后弹出一个上传图片的窗体,选择图片再进行上传,这样在form提交时,提交的参数会少一点.) 说明:跨域上传文件时: a.新加irame <iframe name="upload" style="display:none"></iframe> b. <form id="form_upload_pic" metho

springcloud采坑--Zuul上传文件报java.nio.charset.IllegalCharsetNameException: UTF-8;boundary=sqgzzmMxl1UPdIp0IAYnQgUIAr9yNewVAzKIX

报错日志: 2018-12-17 10:01:19,688 ERROR [io.undertow.request] (default task-3) UT005023: Exception handling request to /xxx/app/bannerMaterialManager/uploadBannerSysGoodsPicture: java.nio.charset.IllegalCharsetNameException: UTF-8;boundary=sqgzzmMxl1UPdI

问题集录02--文件上传(可跨域)

之前工作中遇到了表单跨域上传的问题,寻觅了挺久,才找到解决方法,在此记录. 一.使用from表单上传 工作原理:直接表单提交,访问ssc_media的对应接口 架构说明:使用的是SpringBoot微服务架构,ssc_web负责前端页面和实现对应的后台接口. ssc_media负责把图片和文件上传到mongodb. ${temp}:使用了thymeleaf模块,是一个url路径,指向ssc_media模块的上传文件接口. <body> <!--直接调用media模块的接口--> &

关于上传文件的跨域问题

在进行新框架开发的过程中,需要自定义页面组件实现脱离表单的文件(图片)上传,考虑过wex5自带的attachmentsimple的自定义写法很难受,就改用了第三方插件webuploader来实现选择文件后调用服务端的上传文件接口实现自动上传. 中间遇到过跨域问题,即服务端所在接口域名与插件包(前端)不在同一域名下,但是由于格式是文件,所以必须采用post传输方式 解决方法: 利用CORS实现POST方式跨域请求数据 CORS全名Cross-Origin Resource Sharing,顾名思义

flash上传控件跨域

工作中需要使用百度开发的ueditor,但服务器部署中前端代码和后端代码在不同的域名下,现已解决的前端调后端代码的跨域问题.可是,ueditor中的上传图片flash控件也涉及跨域问题,经过查找发现可以通过在后端域名根目录下增加一个crossdomain.xml文件即可解决上传控件的跨域问题.crossdomain.xml文件内容如下: 1 <?xml version="1.0"?> 2 <!DOCTYPE cross-domain-policy SYSTEM &qu

网页上传插件之WebUploader---跨域上传遇到的问题总结

问题 用WebUploader网页上传插件进行跨域上传的时候,只有IE可以成功,经过1天的调试发现问题所在 在进行AJAX进行上传的时候,会先发送一个OPTIONS的预检请求,然而在IIS的配置里面 没有允许OPTIONS的请求 所以我在服务端加断点调试发现请求根本进不去服务端的方法,而用IE的时候,IE根本没有预检请求,所以IE就可以调试成功 解决办法 加入允许OPTIONS的条件,再次进行测试,问题解决 贴上服务端的代码吧,一个一般处理程序 <%@ WebHandler Language=&qu

PHP漏洞全解(九)-文件上传漏洞

本文主要介绍针对PHP网站文件上传漏洞.由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意PHP文件,并能够将这些文件传递给 PHP解释器,就可以在远程服务器上执行任意PHP脚本,即文件上传漏洞. 一套web应用程序,一般都会提供文件上传的功能,方便来访者上传一些文件. 下面是一个简单的文件上传表单 <form action="upload.php" method="post" encty

在线HTML文档编辑器使用入门之图片上传与图片管理的实现

1 在线HTML文档编辑器使用入门之图片上传与图片管理的实现: 2 官方网址: http://kindeditor.net/demo.php 3 开发步骤: 4 1.开发中只需要导入选中的文件(通常在 webapp 下,建立 editor 文件夹 ) 5 导入:lang.plugins.themes.kindeditor.js/kindeditor-min.js-->放在editor文件夹下 6 2.在页面上引入相关的js&css文件 7 <!-- 导入Kindeditor相关文件 -