成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

帶你玩轉SpringMVC自定義HTTP請求響應數據轉換

開發 前端
自定義HttpMessageConverter是Spring MVC中一個強大的工具,它可以幫助開發者更加靈活地控制數據轉換的過程,滿足特定的需求。

環境:SpringBoot2.7.12

1. 簡介

在Spring MVC中,HttpMessageConverter主要用于將HTTP請求的輸入內容轉換為指定的Java對象,以及將Java對象轉換為HTTP響應的輸出內容。這種靈活的消息轉換機制就是利用HttpMessageConverter來實現的。

Spring MVC提供了多個默認的HttpMessageConverter實現,包括處理JSON、XML、文本等格式的Converter。另外,我們也可以自定義HttpMessageConverter來處理其他格式的數據。

Spring MVC提供了兩個注解:@RequestBody和@ResponseBody,分別用于完成請求報文到對象和對象到響應報文的轉換。

然而,有時候默認的HttpMessageConverter無法滿足特定的需求,例如,當我們需要處理的數據格式沒有默認的Converter時,或者我們需要對現有的Converter進行擴展時,就需要自定義HttpMessageConverter。

自定義HttpMessageConverter可以讓我們更加靈活地控制數據轉換的過程,例如我們可以自定義轉換規則、異常處理等。

接下來我們通過一個實例講解如何自定義HttpMessageConverter。

需求

接口請求數據格式:

xxx|yyy|zzz|...

接口返回JSON數據格式

{
    "xxx": xxx,
    "yyy": yyy,
    "zzz": zzz,
    ...
}

其實就上面的數據格式,我們完全可以不用自定義HttpMessageConverter也是完全可以實現的。我們這里主要就是教大家如何在特殊的需求下實現特定的數據轉換處理。

2. 實戰案例

自定義HttpMessageConverter轉換器

public class PackHttpMessageConverter implements HttpMessageConverter<Object> {
    
  // 設置自定義的Content-Type類型,這樣就限定了只有請求的內容類型是該類型才會使用該轉換器進行處理
  private static final MediaType PACK = new MediaType("application", "pack", StandardCharsets.UTF_8) ;


  // 判斷當前轉換器是否能夠讀取數據
  @Override
  public boolean canRead(Class<?> clazz, MediaType mediaType) {
    return PACK.equals(mediaType) ;
  }
  // 判斷當前轉換器是否可以將結果數據進行輸出到客戶端
  @Override
  public boolean canWrite(Class<?> clazz, MediaType mediaType) {
    return true ;
  }
  // 返回當前轉換器只支持application/pack類型的數據格式
  @Override
  public List<MediaType> getSupportedMediaTypes() {
    return Arrays.asList(PACK) ;
  }


  // 從請求中讀取數據
  @Override
  public Object read(Class<? extends Object> clazz, HttpInputMessage inputMessage)
      throws IOException, HttpMessageNotReadableException {
    InputStream is = inputMessage.getBody() ;
    String res = IOUtils.toString(is, StandardCharsets.UTF_8) ;
    // 這里簡單處理只針對Users類型的對象處理
    if (clazz == Users.class) {
      try {
        // 創建實例
        Users target = (Users) clazz.newInstance() ;
        String[] s = res.split("\\|");
        target.setId(Long.valueOf(s[0])) ;
        target.setName(s[1]) ;
        target.setAge(Integer.valueOf(s[2])) ;
        target.setIdNo(s[3]) ;
        return target ;
      } catch (InstantiationException | IllegalAccessException e) {
        e.printStackTrace() ;
      }
    }
    return null ;
  }


  // 將Controller方法返回值寫到客戶端
  @Override
  public void write(Object t, MediaType contentType, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {
    // 設置響應頭為json格式
    outputMessage.getHeaders().add("Content-Type", "application/json;charset=UTF-8") ;
    ObjectMapper mapper = new ObjectMapper() ;
    OutputStream os = outputMessage.getBody();
    // 輸出結果內容
    os.write(mapper.writeValueAsString(t).getBytes(StandardCharsets.UTF_8)) ;
    os.flush(); 
  }
  
}


將PackHttpMessageConverter注冊到容器中

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
  
  @Override
  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(new PackHttpMessageConverter()) ;
  }
}

到這里自定義HttpMessageConverter及注冊到容器中就全部完成了,開發還是比較簡單,接下來做測試

接口

// 方法非常簡單還是用的那些常用的類,@RequestBody接收請求body中的內容
@PostMapping("/i")
public Object i(@RequestBody Users user) {
  System.out.println(handlerAdapter) ;
  return user ;
}

通過Postman測試接口

設置請求的header

圖片圖片

圖片圖片

似乎沒有任何的問題,其實你只要在寫的方法中打印下日志,或者調試下,你會發現你的write方法根本就沒有被調用,也就是說寫數據并沒有使用到我們自定義的實現,這是因為有優先級比我們自定義的轉換器高,所以要想讓寫消息也調用自定義的。我們需要如下修改注冊方式:

public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
  converters.add(0, new PackHttpMessageConverter()) ;
}

這樣我們自定義的轉換器就排到了第一的位置,這樣就會調用我們自定義的write方法。

以上就是自定義HttpMessageConverter全部內容。

3. 實現原理

請求參數由于添加了@RequestBody,所以方法的參數解析器使用的是RequestResponseBodyMethodProcessor。

public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
  protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,
      Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
    // ...
    // 讀取請求數據;調用父類方法
    Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
    // ...
  }
}

AbstractMessageConverterMethodArgumentResolver

public abstract class AbstractMessageConverterMethodArgumentResolver {
  protected <T> Object readWithMessageConverters(...) {
    // ...
    // 遍歷所有的消息轉換器
    for (HttpMessageConverter<?> converter : this.messageConverters) {
        Class<HttpMessageConverter<?>> converterType = (Class<HttpMessageConverter<?>>) converter.getClass();
        GenericHttpMessageConverter<?> genericConverter = (converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter<?>) converter : null);
        // 判斷當前轉換器是否讀,也就上面我們自定義中實現的canRead方法
        if (genericConverter != null ? genericConverter.canRead(targetType, contextClass, contentType) :
            (targetClass != null && converter.canRead(targetClass, contentType))) {
          if (message.hasBody()) {
            HttpInputMessage msgToUse = getAdvice().beforeBodyRead(message, parameter, targetType, converterType);
            // 讀取具體的數據內容
            body = (genericConverter != null ? genericConverter.read(targetType, contextClass, msgToUse) : ((HttpMessageConverter<T>) converter).read(targetClass, msgToUse));
            body = getAdvice().afterBodyRead(body, msgToUse, parameter, targetType, converterType);
          }
          else {
            body = getAdvice().handleEmptyBody(null, message, parameter, targetType, converterType);
          }
          break;
        }
      }
  }
}

原理也比較的簡單。

自定義HttpMessageConverter是Spring MVC中一個強大的工具,它可以幫助開發者更加靈活地控制數據轉換的過程,滿足特定的需求。

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2023-12-04 07:27:54

SpringMVC方法

2022-12-07 08:56:27

SpringMVC核心組件

2022-06-20 08:26:39

Spring容器類型轉換

2022-11-01 11:15:56

接口策略模式

2019-01-27 14:37:47

數據HTTP服務

2021-07-11 17:17:08

.NET 授權自定義

2021-08-09 10:31:33

自定義授權響應

2009-08-12 14:53:50

C#類型轉換函數

2023-10-06 10:47:25

Mybatis類型轉換

2015-02-12 15:33:43

微信SDK

2011-07-04 14:08:02

C++

2015-02-12 15:38:26

微信SDK

2024-01-05 15:28:06

鴻蒙數據同步GlobalThis

2009-08-28 17:45:19

C#自定義數據

2016-12-26 15:25:59

Android自定義View

2016-11-16 21:55:55

源碼分析自定義view androi

2023-06-06 08:01:18

自定義接口響應

2011-06-23 10:49:13

Qt 自定義信號

2025-05-12 08:00:55

2021-08-13 08:36:15

SpringMVC自定義
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产亚洲精品成人av久久ww | 希岛爱理在线 | 在线视频一区二区 | 91久久爽久久爽爽久久片 | 亚洲一区二区在线播放 | 在线免费观看日本视频 | 欧美日韩中文字幕在线 | 亚洲国产一区在线 | 91在线观 | 久久av在线播放 | 久久九九色 | 亚洲一区中文字幕 | 国产一区二区在线视频 | 久久久精品国产 | 91视频91 | 色婷婷av777 av免费网站在线 | 一级在线毛片 | 国产三级精品三级在线观看四季网 | 日韩欧美在线视频 | 日韩欧美精品 | 日韩国产黄色片 | 成人精品国产一区二区4080 | 日韩欧美日韩在线 | 欧美日韩大片 | 日日夜夜精品视频 | 久久国产精品99久久久久久丝袜 | 亚洲欧美在线一区 | 国产福利在线小视频 | 91精品国产综合久久久久久首页 | 国产精品视频网 | 国产成人在线视频 | 一级视频在线免费观看 | 偷偷操视频| 国产精品99久久久久久www | 狠狠色网 | 精品综合网 | 伊人免费视频二 | 在线一区二区三区 | 国产91av视频 | 中国一级特黄视频 | 成人特级毛片 |