第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定

Spring Security 錯誤信息 國際化

標(biāo)簽:
Java SpringBoot

功能开发中,我们会有这种需求,希望所有的数据返回统一的格式,包含状态码,数据,错误信息,当前时间,比如:

{"code":200,"data":null,"message":"OK","timestamp":1559292578716}

首先我们需要有这么一个类

@Data
public class Result<T> {
    private long timestamp;
    private String message;
    private int code=SUCCESS;
    private T data;
    @Data
    public static class Builder<T> {
        //部分代码略
    }
}

但是我们不能在每一个Controller上的返回格式都定义为Result

Spring Boot 如何在不改变原有的Controller的基础上实现呢?
我们可以借助Spring提供的ResponseBodyAdvice实现

public interface ResponseBodyAdvice<T> {
    boolean supports(MethodParameter var1, Class<? extends HttpMessageConverter<?>> var2);

    @Nullable
    T beforeBodyWrite(@Nullable T var1, MethodParameter var2, MediaType var3, Class<? extends HttpMessageConverter<?>> var4, ServerHttpRequest var5, ServerHttpResponse var6);
}

该接口只有两个方法supportsbeforeBodyWrite

  • supports 方法返回boolean,判断是否支持Controller的返回类型
  • beforeBodyWrite 写出之前的处理,此文中主要依靠此方法,T var1就是Controller返回的对象

写一个我们自己的实现

@ControllerAdvice()
public class ResponseAdvisor implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {
        return new Result.Builder<>().data(body).build();
    }
}

系统中原有的Controller

@RestController
public class DemoController {
    @GetMapping("/echo/{name}")
    public String echo(@PathVariable("name") String name){
        return "hello:"+name;
    }
    @GetMapping("/user/{id}")
    public User getUserById(@PathVariable("id") Long id){
        User user=new User(id,"Lucy",18);
        return user;
    }
    @GetMapping("/download")
    public ResponseEntity<FileSystemResource> download() {
        File file = new File("d:/1.jpg");
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        try {
            headers.add("Content-Disposition", "attachment; filename=" + new String(file.getName().getBytes("GB2312"),"ISO-8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(new FileSystemResource(file));
    }
}

分别进行测试

{
    "timestamp": 1559293805111, 
    "message": "OK", 
    "code": 200, 
    "data": {
        "id": 1, 
        "name": "Lucy", 
        "age": 18
    }
}
java.lang.ClassCastException: com.podigua.demo.core.Result cannot be cast to java.lang.String
java.lang.ClassCastException: com.podigua.demo.core.Result cannot be cast to org.springframework.core.io.Resource

三个测试.发现有两个出错, 出错的原因是找不到对应的HttpMessageConverter,HttpMessageConverter 是一组消息转换器,以下列出部分MessageConverter

  • StringHttpMessageConverter 负责字符串类型的数据的读取或者写出
  • ByteArrayHttpMessageConverter 负责二进制格式数据的读取或者写出
  • ResourceHttpMessageConverter 负责资源文件的读取或者写出
  • FormHttpMessageConverter 负责读取form提交的数据application/x-www-form-urlencoded
  • MappingJacksonHttpMessageConverter 负责json格式数据的读取或者写出

原因就是缺少 MappingJackson2HttpMessageConverterResourceHttpMessageConverter

我们调整下代码,增加这两个消息转换器

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer  {
	@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new MappingJackson2HttpMessageConverter());
        converters.add(1, new ResourceHttpMessageConverter());
    }
}

资源类数据,不能按照这种格式返回,最终返回的是文件流,我们调整下代码ResponseAdvisorbeforeBodyWrite方法,若返回值已经是Result类型也不需要处理

@Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {
        if (body instanceof Resource) {
            return body;
        }
        if (body instanceof Result) {
            return body;
        }
        return new Result.Builder<>().data(body).build();
    }

Coltroller抛出了异常呢? 需要AOP捕获异常,并将异常信息与状态码封装为Result的数据即可

项目github地址

點擊查看更多內(nèi)容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
JAVA開發(fā)工程師
手記
粉絲
3
獲贊與收藏
9

關(guān)注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊有機(jī)會得

100積分直接送

付費專欄免費學(xué)

大額優(yōu)惠券免費領(lǐng)

立即參與 放棄機(jī)會
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報

0/150
提交
取消