What is the best way to return different types of ResponseEntity in Spring MVC or Spring-Boot

后端 未结 12 1484
南旧
南旧 2020-12-07 09:15

I have written simple rest application using Spring MVC 4 (or Spring-Boot). Within the controller I have return ResponseEntity. But in some cases I want to give

相关标签:
12条回答
  • 2020-12-07 09:34

    You can use a map with your object or string like bellow :

    @RequestMapping(value = "/path", 
            method = RequestMethod.GET, 
            produces = MediaType.APPLICATION_JSON_VALUE)
        @ResponseBody
        public ResponseEntity<Map<String,String>> getData(){
    
        Map<String,String> response = new HashMap<String, String>();
    
        boolean isValid = // some logic
        if (isValid){
            response.put("ok", "success saving data");
            return ResponseEntity.accepted().body(response);
        }
        else{
            response.put("error", "an error expected on processing file");
            return ResponseEntity.badRequest().body(response);
        }
    
    }
    
    0 讨论(0)
  • 2020-12-07 09:42

    Note: if you upgrade from spring boot 1 to spring boot 2 there is a ResponseStatusException which has a Http error code and a description.

    So, you can effectively use generics they way it is intended.

    The only case which is a bit challenging for me, is the response type for a status 204 (ok with no body). I tend to mark those methods as ResponseEntity<?>, because ResponseEntity<Void> is less predictive.

    0 讨论(0)
  • 2020-12-07 09:43

    Spring 2 introduced ResponseStatusException using this you can return String, different HTTP status code, DTO at the same time.

    @PostMapping("/save")
    public ResponseEntity<UserDto> saveUser(@RequestBody UserDto userDto) {
        if(userDto.getId() != null) {
            throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"A new user cannot already have an ID");
        }
        return ResponseEntity.ok(userService.saveUser(userDto));
    }
    
    0 讨论(0)
  • 2020-12-07 09:46

    You can return generic wildcard <?> to return Success and Error on a same request mapping method

    public ResponseEntity<?> method() {
        boolean b = // some logic
        if (b)
            return new ResponseEntity<Success>(HttpStatus.OK);
        else
            return new ResponseEntity<Error>(HttpStatus.CONFLICT); //appropriate error code
    }
    

    @Mark Norman answer is the correct approach

    0 讨论(0)
  • 2020-12-07 09:47

    I used to use a class like this. The statusCode is set when there is an error with the error message set in message. Data is stored either in the Map or in a List as and when appropriate.

    /**
    * 
    */
    package com.test.presentation.response;
    
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * A simple POJO to send JSON response to ajax requests. This POJO enables  us to
     * send messages and error codes with the actual objects in the application.
     * 
     * 
     */
    @SuppressWarnings("rawtypes")
    public class GenericResponse {
    
    /**
     * An array that contains the actual objects
     */
    private Collection rows;
    
    /**
     * An Map that contains the actual objects
     */
    private Map mapData;
    
    /**
     * A String containing error code. Set to 1 if there is an error
     */
    private int statusCode = 0;
    
    /**
     * A String containing error message.
     */
    private String message;
    
    /**
     * An array that contains the actual objects
     * 
     * @return the rows
     */
    public Collection getRows() {
        return rows;
    }
    
    /**
     * An array that contains the actual objects
     * 
     * @param rows
     *            the rows to set
     */
    public void setRows(Collection rows) {
        this.rows = rows;
    }
    
    /**
     * An Map that contains the actual objects
     * 
     * @return the mapData
     */
    public Map getMapData() {
        return mapData;
    }
    
    /**
     * An Map that contains the actual objects
     * 
     * @param mapData
     *            the mapData to set
     */
    public void setMapData(Map mapData) {
        this.mapData = mapData;
    }
    
    /**
     * A String containing error code.
     * 
     * @return the errorCode
     */
    public int getStatusCode() {
        return statusCode;
    }
    
    /**
     * A String containing error code.
     * 
     * @param errorCode
     *            the errorCode to set
     */
    public void setStatusCode(int errorCode) {
        this.statusCode = errorCode;
    }
    
    /**
     * A String containing error message.
     * 
     * @return the errorMessage
     */
    public String getMessage() {
        return message;
    }
    
    /**
     * A String containing error message.
     * 
     * @param errorMessage
     *            the errorMessage to set
     */
    public void setMessage(String errorMessage) {
        this.message = errorMessage;
    }
    

    }

    Hope this helps.

    0 讨论(0)
  • 2020-12-07 09:48

    Using custom exception class you can return different HTTP status code and dto object.

    @PostMapping("/save")
    public ResponseEntity<UserDto> saveUser(@RequestBody UserDto userDto) {
        if(userDto.getId() != null) {
            throw new UserNotFoundException("A new user cannot already have an ID");
        }
        return ResponseEntity.ok(userService.saveUser(userDto));
    }
    

    Exception class

    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.ResponseStatus;
    
    @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "user not found")
    public class UserNotFoundException extends RuntimeException {
    
        public UserNotFoundException(String message) {
    
            super(message);
        }
    }
    
    0 讨论(0)
提交回复
热议问题