我有一個 Spring Boot Rest API。我想創建用戶并對其電子郵件和用戶名設定唯一約束。到目前為止效果很好。以下是主要的類和方法:
@Entity
@NoArgsConstructor
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true)
@NotNull
private String email;
@Column(unique = true)
@NotNull
private String username;
@NotNull
private String password;
public User(String email, String username, String password) {
this.email = email;
this.password = password;
this.username = username;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SignupRequest {
@NotNull
private String email;
@NotNull
private String username;
@NotNull
private String password;
}
@CrossOrigin(value = "*")
@PostMapping("/signup")
public ResponseEntity<?> signup(@Valid @RequestBody SignupRequest signupRequest) {
signupService.signup(signupRequest);
return ResponseEntity.ok().build();
}
@Service
public class SignupServiceImpl implements SignupService {
@Override
public void signup(SignupRequest signupRequest) throws MessagingException, UnsupportedEncodingException {
User user = new User();
User user = new User(signupRequest.getEmail(), signupRequest.getUsername(), signupRequest.getPassword());
user = userRepository.save(user);
}
}
@Repository
@Component
public interface UserRepository extends CrudRepository<User, Long> {}
現在,問題是,當我使用已經存在的用戶名或電子郵件向該端點發送 POST 請求時,我只會收到 http 回應 500 內部服務器錯誤。但我想回傳一個不同的狀態代碼和一些錯誤訊息,表明電子郵件/用戶名已經存在。
現在兩個問題:
- 如何全域修改回應?我可以
userRepository.save(user)用 try catch 塊包圍該方法,但我必須在單獨保存用戶的所有方法中都這樣做。我可以在全球范圍內定義類似的東西嗎? - 該
userRepository.save(user)方法只回傳一個。JdbcSQLIntegrityConstraintViolationException帶有非常冗長的訊息。有沒有辦法清楚地確定到底出了什么問題(唯一用戶名約束失敗,唯一電子郵件約束失敗,......)?我可以通過在 userRepository 中撰寫一個方法來檢查具有該用戶名或電子郵件的用戶是否存在,但這對我來說看起來像是很多不必要的 sql 查詢。有沒有更好的辦法?
uj5u.com熱心網友回復:
要回答您的第一個問題,您可以通過 spring 例外處理機制全域處理例外。您可以使用 spring ControllerAdvice。您可以在此處設定通用錯誤回應和自定義 http 代碼。這是 ControllerAdvice 的示例
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(UserNotFoundException.class)
public final ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException ex, WebRequest request) {
String details = ex.getLocalizedMessage();
ErrorResponse error = new ErrorResponse(ApplicationConstants.RECORD_NOT_FOUND, details);
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public final ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex, WebRequest request) {
String details = ex.getLocalizedMessage();
ErrorResponse error = new ErrorResponse(ApplicationConstants.SERVER_ERROR, details);
return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
public class ErrorResponse
{
public ErrorResponse(String message, String details) {
super();
this.message = message;
this.details = details;
}
private String message;
private String details;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
現在關于第二個問題,您可以遍歷所有原因并檢查唯一約束名稱以找出違反了什么例外。但更好的方法是先檢查,如果找到則拋出錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/373462.html
