【问题标题】:Best way to add the custom exception for the spring boot code为 Spring Boot 代码添加自定义异常的最佳方法
【发布时间】:2019-02-25 11:13:45
【问题描述】:

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

假设在 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


    【解决方案1】:

    处理任何应用程序特定异常的最佳方法是创建自定义异常类。创建一个说 com.randomorg.appname.exception 的包。在其中创建一个扩展 Java 异常类的 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,这样您可以更好地组织异常处理。如果您需要更多帮助,请告诉我。乐于助人。

    【讨论】:

    • 创建这个之后,我应该在我的控制器中做些什么。
    • 对于 POST 和 PUT 方法,所有可能的异常是什么... - 假设如果我们在正文中提供相同的 id 并尝试发布该请求,那么将发送相同的请求知道。 - 假设如果我们对具有相同 ID 的数据进行修改,那么如果我们尝试发布该 ID 将得到更新 ryt。
    【解决方案2】:

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

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

    public class ErrorResponse {
         private String message;
    
         public String getMessage() {
           return message;
        }
    
        public void setMessage(String message) {
          this.message = message;
        }
    }
    

    方法 1. 在您的 Controller 方法中。

        @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 步:从您的控制器或服务中抛出 Not found 异常:

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

    【讨论】:

    • 我遵循了您的第二种方法,即通过创建一个类 NoRecordFoundException 类并创建一个 GlobalExceptionHandler 类来全局处理异常,最后添加了 throw new NoRecordFoundException();在控制器中。
    • 运行良好或有任何问题??
    • 但是对于这一行@ResponseStatus(HttpStatus.NOT_FOUND) 得到错误:HttpStatus 无法解析为变量
    • 你能检查一下HttpStatus吗?对于未找到
    • 检查您的包中导入的内容,而不是检查stackoverflow.com/questions/30649119/…
    猜你喜欢
    • 2019-12-10
    • 2019-12-12
    • 2021-07-10
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多