Spring Boot Rest API 处理唯一约束
Posted
技术标签:
【中文标题】Spring Boot Rest API 处理唯一约束【英文标题】:Spring Boot Rest API handling unique constraint 【发布时间】:2022-01-09 01:21:43 【问题描述】:我有一个 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 Internal Server Error。但我想返回一个不同的状态码和一些错误消息,表明电子邮件/用户名已经存在。
现在有两个问题:
-
如何全局修改响应?我可以用 try catch 块包围
userRepository.save(user)
方法,但我必须在我单独保存用户的所有方法中这样做。我可以在全球范围内定义类似的东西吗?
userRepository.save(user)
方法只返回一个。 JdbcSQLIntegrityConstraintViolationException
带有非常冗长的消息。有没有办法清楚地确定到底出了什么问题(唯一用户名约束失败,唯一电子邮件约束失败,......)?我可以通过在 userRepository 中编写一个方法来检查具有该用户名或电子邮件的用户是否存在,但这对我来说看起来像是很多不必要的 sql 查询。有没有更好的方法?
【问题讨论】:
【参考方案1】:回答您的第一个问题,您可以通过 Spring 异常处理机制全局处理异常。您可以使用弹簧控制器建议。在这里您可以设置通用错误响应和自定义 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;
现在关于第二个问题,您可以遍历所有原因并检查唯一约束名称以找出违反了哪些异常。但更好的方法是先检查,如果发现则抛出错误。
【讨论】:
谢谢!完美运行:)以上是关于Spring Boot Rest API 处理唯一约束的主要内容,如果未能解决你的问题,请参考以下文章
ControllerAdvice 的异常处理程序在使用 Spring Boot 的 Rest API 获取请求中不起作用。如何解决?
使用 Spring Boot 和 JWT 保护 REST Api
Spring Boot Rest Controller 通用 POST 类型