wybourn
wybourn

Reputation: 678

Spring Controller always produce json

Is there anyway to force spring to always produce json, even an empty json object if there's no data to return. Our services go through another service that rejects any response that isn't valid json (regardless of status code). It's not nice but we have no control of this.

With spring controllers you can tell them to produce json, but this only works when there's content to return. Is there a quick and elegant way to make all responses be 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();
}

The simply fix here is to simply add an if statement to check for null. But that's ugly as I'll have to manually set the header and the response body.

I'm hoping someone knows of a nicer way?

Thanks

Upvotes: 0

Views: 1942

Answers (2)

Vasu
Vasu

Reputation: 22422

If you want all responses to return application/json, then you can set this at a single place by overriding postHandle() from HandlerInterceptorAdapter:

@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");
         }
     }
}

You can look here

Upvotes: 2

Angelo Immediata
Angelo Immediata

Reputation: 6944

You may wrap the response in a "Container" object For example I use this 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

}

Then in my controllers I use this strategy:

@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);
    }

I hope this can be useful

Angelo

Upvotes: 0

Related Questions