为 Spring Boot 代码添加自定义异常的最佳方法

问题描述 投票:0回答:3

发生异常时如何显示相应的错误信息。

假设在 GET 方法中如果没有找到数据,它应该显示自定义异常消息。

同样,如果我们尝试删除不可用的数据。

Car.java

package com.car_rental_project.car_project;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity

public class Car {

    @Id
    private String id;
    private String modelname;
    private String type;
    private String year_of_registration;
    private String seating_capacity;
    private String cost_per_day;
    private String milleage;
    private String pincode;
    private String contact_number;
    private String email;

    public Car() {

    }

    public Car(String id, String modelname, String type, String year_of_registration, String seating_capacity,String cost_per_day, String milleage, String pincode, String contact_number, String email) {
        super();
        this.id = id;
        this.modelname = modelname;
        this.type = type;
        this.year_of_registration = year_of_registration;
        this.seating_capacity = seating_capacity;
        this.cost_per_day = cost_per_day;
        this.milleage = milleage;
        this.pincode = pincode;
        this.contact_number = contact_number;
        this.email = email;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getModelname() {
        return modelname;
    }

    public void setModelname(String modelname) {
        this.modelname = modelname;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getYear_of_registration() {
        return year_of_registration;
    }

    public void setYear_of_registration(String year_of_registration) {
        this.year_of_registration = year_of_registration;
    }

    public String getSeating_capacity() {
        return seating_capacity;
    }

    public void setSeating_capacity(String seating_capacity) {
        this.seating_capacity = seating_capacity;
    }

    public String getCost_per_day() {
        return cost_per_day;
    }

    public void setCost_per_day(String cost_per_day) {
        this.cost_per_day = cost_per_day;
    }

    public String getMilleage() {
        return milleage;
    }

    public void setMilleage(String milleage) {
        this.milleage = milleage;
    }

    public String getPincode() {
        return pincode;
    }

    public void setPincode(String pincode) {
        this.pincode = pincode;
    }

    public String getContact_number() {
        return contact_number;
    }

    public void setContact_number(String contact_number) {
        this.contact_number = contact_number;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

CarService.java

package com.car_rental_project.car_project;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CarService {

    @Autowired
    private CarRepository CarRepository;

    public List<Car> getAllCars() {
        return (List<Car>) CarRepository.findAll();
    }

    public Car getCar(String id) {
        return (Car) CarRepository.findOne(id);

    }

    public void addCar(Car car) {
        this.CarRepository.save(car);
    }

    public void updateCar(String id, Car car) {
        this.CarRepository.save(car);
    }

    public void deleteCar(String id) {
        this.CarRepository.delete(id);;
    }
}

CarController.java

package com.car_rental_project.car_project;

import java.util.List;    
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CarController {

    @Autowired
    private CarService carService;

    @RequestMapping("/car")
    public List<Car> getAllCars() {
        return carService.getAllCars();
    }

    @RequestMapping("/car/{id}")
    public Car getCar(@PathVariable String id) {
        return carService.getCar(id);
            }

    //@PostMapping("/car")
    @RequestMapping(method=RequestMethod.POST, value="/car")
    public String addCar(@RequestBody Car car) {
        carService.addCar(car);
        String response = "{\"success\": true, \"message\": Car has been added successfully.}";
        return response;
    }

    //@RequestMapping(method=RequestMethod.PUT, value="/car/{id}")
    @PutMapping("/car/{id}")
    public String updateCar(@RequestBody Car car, @PathVariable String id) {
        carService.updateCar(id, car);
        String response = "{\"success\": true, \"message\": Car has been updated successfully.}";
        return response;
    }

    //@RequestMapping(method=RequestMethod.DELETE, value="/topics/{id}")
    @DeleteMapping("/car/{id}")
    public String deleteCar(@PathVariable String id) {
        carService.deleteCar(id);
        String response = "{\"success\": true, \"message\": Car has been deleted successfully.}";
        return response;
    }
}
spring-boot error-handling custom-exceptions
3个回答
18
投票

您可以遵循以下一些方法来处理自定义异常。

创建一个 POJO 来处理您的自定义错误消息并放置您想要返回的属性。

public class ErrorResponse {
     private String message;

     public String getMessage() {
       return message;
    }

    public void setMessage(String message) {
      this.message = message;
    }
}

方法 1. 在您的控制器方法中。

    @RequestMapping("/car/{id}")
    public ResponseEntity<?> getCar(@PathVariable String id) {
        Car car = carService.getCar(id);
        if (car == null) {
          ErrorResponse errorResponse = new ErrorResponse();
          errorResponse.setMessage("Record not found");
          return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND)
         }
       return new ResponseEntity<>(car, HttpStatus.OK); 
    }    

方法2:全局处理异常。

第 1 步:创建 NotFound 异常类并扩展为 RunTime Exception。

public class NoRecordFoundException extends RuntimeException {

    public NoRecordFoundException() {
        super();
    }
}

第 2 步:创建全局异常处理程序

@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(NoRecordFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorResponse handleNoRecordFoundException(NoRecordFoundException ex) 
{

    ErrorResponse errorResponse = new ErrorResponse();
    errorResponse.setMessage("No Record Found");
    return errorResponse;
}

//同样可以处理内部的异常错误

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ErrorResponse handleDefaultException(Exception ex) {
    ErrorResponse response = new ErrorResponse();
    response.setMessage(ex.getMessage());
    return response;
}
}

第 3 步:从控制器或服务抛出未找到异常:

        @RequestMapping("/car/{id}")
        public ResponseEntity<?> getCar(@PathVariable String id) {
            Car car = carService.getCar(id);
            if (car == null) {
             throw new NoRecordFoundException();
             }
           return new ResponseEntity<>(car, HttpStatus.OK); 
        }    

方法 3:在控制器内创建

@ExceptionHandler
并抛出

 @ExceptionHandler(NoRecordFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ResponseBody
    public ErrorResponse handleNoRecordFoundException(NoRecordFoundException ex) {

        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage("No Record Found");
        return errorResponse;
    }

0
投票

处理任何应用程序特定异常的最佳方法是创建自定义异常类。创建一个名为 com.randomorg.appname.exception 的包。在其中创建一个扩展 Java 的 Exception 类的 appException 类。

public class CustomAppException extends Exception {

    private String requestId;

    // Custom error message
    private String message;

    // Custom error code representing an error in system
    private String errorCode;

    public CustomAppException (String message) {
            super(message);
            this.message = message;
        }

        public CustomAppException (String requestId, String message, String errorCode) {
            super(message);
            this.requestId = requestId;
            this.message = message;
            this.errorCode = errorCode;
        }

        public String getRequestId() {
            return this.requestId;
        }

        public void setRequestId(String requestId) {
            this.requestId = requestId;
        }

        @Override
        public String getMessage() {
            return this.message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public String getErrorCode() {
            return this.errorCode;
        }

        public void setErrorCode(String errorCode) {
            this.errorCode = errorCode;
        }
    }
}

完成此操作后,请确保您的控制器使用此异常,这样您就可以自定义任何异常以使其基于应用程序。

在您的情况下,您的方法(如 addCar、getCar),您可以说它抛出 CustomAppException,然后您可以在简单的 try catch 块中处理它。

为了进一步即兴发挥,您可以通过扩展 CustomAppException 类来进一步专门化异常,例如 MyCustomException 扩展 CustomAppException,这样您就可以更好地组织异常处理。如果您需要更多帮助,请告诉我。很乐意提供帮助。


0
投票

如果你不想实现ControllerAdvice而只需要一个快速的自定义异常,你可以使用ResponseStatusException; 根据https://www.baeldung.com/spring-response-status-exception

© www.soinside.com 2019 - 2024. All rights reserved.