JavaでExcelをエクスポートする際のエラー:[class xxx]に対するコンバーターが見つからない

エラーメッセージ:

org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class xxx] with preset Content-Type 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'

解決策

エラー内容は「指定されたContent-Typeに対応するコンバーターが見つからない」という意味です。この問題を解決するには以下の2つの方法があります。

  • メソッドの戻り値型をvoidに変更する
  • response.reset()を使ってレスポンスのContent-Typeをクリアし、適切なコンバーターを選択させる。ただし、これによりフロントエンド側にもContent-Typeが設定されず、ファイル形式を判別できなくなるため、フロントエンドで明示的に設定する必要がある

問題コード例

エクスポート機能自体は正常に動作しますが、ログには「戻り値の変換に失敗した」というエラーが出力されます。これは実際には機能に影響しませんが、ログの可読性を損ねます。

public MessageResp<String> exportExcel(@RequestBody Req req, HttpServletResponse response) throws Exception {
    try (ServletOutputStream out = response.getOutputStream()) {
        String fileName = URLEncoder.encode("導出テーブル.xlsx", "UTF-8");
        response.reset();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);
        DgExcelUtil.getXlsx("導出シート", exportClass, titleList, exportList).write(out);
    } catch (Exception e) {
        LOGGER.error("エクスポートエラー:", e);
        throw new SmkException(ErrorCode.FAIL, "エクスポートエラー");
    }
    return new MessageResp<>(); // 問題の返却値
}

エラーログ詳細

エラーログのスタックトレースは以下の通りです:

org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.sk.financial.dg.supervision.response.MessageResp] with preset Content-Type 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
	at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:312)
	...

原因分析

エラー発生箇所のAbstractMessageConverterMethodProcessor.writeWithMessageConvertersメソッドを見ると、以下のような処理が行われています。

  1. レスポンスヘッダーからContent-Typeを取得し、selectedMediaTypeに設定
  2. もしContent-Typeが指定されていない場合、リクエストのAcceptヘッダーとサポートされているメディアタイプに基づいて自動選定

その後、選択されたselectedMediaTypeを使ってコンバーターを検索します。しかし、指定されたContent-Typeと返却値の型が一致しない場合、コンバーターが見つからないため例外がスローされます。

この問題を回避するには、以下のいずれかの方法をとります:

  • 返却値をvoidに変更してSpringがコンバーター処理を行わないようにする
  • レスポンスのContent-Typeをクリアし、Springが自動的に適切なコンバーターを選ぶようにする

タグ: Java Spring Excel HTTP Content-Type

7月25日 21:50 投稿