2016-11-04 4 views
0

返すデータがない場合、スプリングが常にjsonを生成するように強制します。空のjsonオブジェクトも強制します。 サービスは、有効なjson(ステータスコードに関係なく)でない応答を拒否する別のサービスを経由します。それはいいものではありませんが、私たちはこれを支配しません。スプリングコントローラは常にjsonを生成します

スプリングコントローラでは、jsonを生成するように指示できますが、これは返すコンテンツがある場合にのみ機能します。すべての回答をjsonにするためのすばやくエレガントな方法はありますか?

@RequestMapping(value = "/test", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
public 
@ResponseBody 
ResponseEntity<String> test(){ 
    // if this returns null or an empty string the response body will be emtpy 
    // and the content-type header will not be set. 
    return service.getData(); 
} 

単純にここで修正するには、if文を追加してnullをチェックするだけです。しかし、私は手動でヘッダとレスポンスボディを設定する必要があるので、これは醜いです。

私は誰かがより良い方法を知ってほしいと思っていますか?

おかげ

+0

どのように見ることができますサービスはヌル/何も返さず、ExceptionHandlerを使って適切なレスポンスとヘッダを設定しますか? – Mubin

答えて

1

ELO:

@Component 
public class ResponseInterceptor extends HandlerInterceptorAdapter { 

    @Override 
    public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, 
      final ModelAndView modelAndView) throws IOException { 
     if (response.getContentType() == null || response.getContentType().equals("")) { 
      response.setContentType("application/json"); 
     } 
    } 
} 

あなたは場合に例外を投げるについてhere

+0

ありがとう、これは私が探していたものです。 – wybourn

0

あなたは、私がこのBaseAjaxResponseを使用たとえば「コンテナ」オブジェクト で応答をラップすることがあります。

public class BaseAjaxResponse implements Serializable 
{ 

    private static final long serialVersionUID = 9087132709920851138L; 
    private int codiceOperazione; 
    private String descrizioneEsitoOperazione; 
    private long numeroTotaleOggetti; 
    private long numeroOggettiRestituiti; 
    private List<? extends Object> payload; 
    //Constructors and getter/setter 

} 

その後、私のコントローラで、私はこの戦略を使用します。

@RequestMapping(method = { RequestMethod.POST }, value = { "/find" }) 
    public ResponseEntity<BaseAjaxResponse> createCandidato(@RequestBody CandidatoDto candidato){ 
     BaseAjaxResponse bar = new BaseAjaxResponse(); 
     HttpStatus statusCode = null; 
     List<Object> payload = null; 
     StopWatch sw = new StopWatch("Find"); 
     try 
     { 
      sw.start(); 
      payload = myService.find(); 
      sw.stop(); 
      if(payload == null || payload.isEmpty()) 
      { 
       statusCode = HttpStatus.NO_CONTENT; 
       bar.setCodiceOperazione(statusCode.value()); 
       bar.setDescrizioneEsitoOperazione("No result"); 
      } 
      else 
      { 
       statusCode = HttpStatus.OK; 
       bar.setCodiceOperazione(statusCode.value()); 
       bar.setDescrizioneEsitoOperazione("Got result");  
       //Set the object count and the number of found objects 
      } 
     } 
     catch (Exception e) 
     { 
      String message = "Errore nell'inserimento di un candidato; "+e.getMessage(); 
      statusCode = HttpStatus.INTERNAL_SERVER_ERROR; 
      bar.setCodiceOperazione(statusCode.value()); 
      bar.setDescrizioneEsitoOperazione(message); 
      logger.error(message, e); 

     } 
     finally 
     { 
      if(sw.isRunning()) 
      { 
       sw.stop(); 
       if(logger.isDebugEnabled()) 
       { 
        logger.debug("CHIUSURA STOPWATCH FORZATA. "+sw.toString()); 
       } 
      } 
     } 

     return new ResponseEntity<BaseAjaxResponse>(bar, statusCode); 
    } 

私はこれが役立つことを望みます。

Angあなたはすべての応答がapplication/jsonを返すようにしたい場合は、あなたがHandlerInterceptorAdapterからpostHandle()をオーバーライドすることで、単一の場所でこれを設定することができます

+0

サービスが文字列を返すので、残念ながらそれは動作しません。私は他の多くのサービスを手掛けています。残念ながら、リファクタリングにはかなり制限があります。 – wybourn

+0

本当に必要なのは、nullまたは空の文字列を空のjsonオブジェクトに変換することです。ラッパーのアプローチの問題は、フィールドを追加することですが、空のjsonオブジェクトが必要です。 – wybourn

+0

それではカスタムメッセージコンバータを使用することができます。このメッセージコンバータでは、あなたが望むようにJSONを処理することができます –

関連する問題