responseEntity.好的,通过复制它来生成畸形响应体



我尝试调用get端点。但是它在我的响应下返回重复的对象,我不知道为什么Spring返回那些畸形的对象

@RestController
@RequestMapping("/v0/api/user")
public class UserResource {
private final UserApplication userApplication;
private final UserRequestResponseAssembler requestResponseAssembler;
public UserResource(UserApplication userApplication, UserRequestResponseAssembler userRequestResponseAssembler) {
this.userApplication = userApplication;
this.requestResponseAssembler = userRequestResponseAssembler;
}
@PostMapping
public ResponseEntity<?> createUser(@Valid @RequestBody UserRequest userRequest) {
UserCreationRequest userCreationRequest = this.requestResponseAssembler.toUserCreationRequest(userRequest);
UserCreationResponse userCreationResponse = this.userApplication.createUser(userCreationRequest);
EntityModel<?> model = this.requestResponseAssembler.toEntityModel(userCreationResponse);
return ResponseEntity.created(model.getRequiredLink(IanaLinkRelations.SELF).toUri()).build();
}
@GetMapping("/{id}")
public ResponseEntity<?> getUserById(@PathVariable("id") String userId) {
UserResponse user = this.userApplication.findById(userId);
EntityModel<UserResponse> entityModel = this.requestResponseAssembler.toEntityModel(user);
return ResponseEntity.ok(entityModel);
}
@RequestMapping(value = "/{email}", method = RequestMethod.HEAD)
public ResponseEntity<?> existByEmail(@PathVariable("email") String email) {
if (userApplication.checkIfUserExistByEmail(email)) return ResponseEntity.status(HttpStatus.FOUND).build();
return ResponseEntity.notFound().build();
}
}

这是一个userResponse记录:


public record UserResponse(String userId,
String firstname, String lastname, String email, String profession) {
}

这是User.class

@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(generator = "ID_GENERATOR")
private Long id;
@Embedded
private UserInformation userInformation;
@Embedded
private AuditInformation auditInformation;
@Embedded
private UserId userId;
@Embedded
private AuthInformation authInformation;
User() {
}
public User(UserInformation userInformation, AuditInformation auditInformation, AuthInformation authInformation, UserId userId) {
this.userInformation = userInformation;
this.userId = userId;
this.auditInformation = auditInformation;
this.authInformation = authInformation;
}
public UserInformation getUserInformation() {
return userInformation;
}
public AuthInformation getAuthInformation() {
return authInformation;
}
public UserId getUserId() {
return userId;
}
public Set<Role> getActiveRoles() {
Set<Role> roles = new HashSet<>();
roles.add(Role.DEFAULT);
return roles;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User user)) return false;
return getUserId().equals(user.getUserId());
}
@Override
public int hashCode() {
return Objects.hash(getUserId());
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userInformation=" + userInformation +
", auditInformation=" + auditInformation +
", userId=" + userId +
", authInformation=" + authInformation +
'}';
}
}

UserId.class


@Embeddable
public class UserId {
@Column(name = "user_id", nullable = false, unique = true)
private final String id;
public UserId() {
this.id = UUID.randomUUID().toString();
}
public UserId(String stringUserId) {
this.id = stringUserId;
}
public String getId() {
return id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof UserId userId)) return false;
return getId().equals(userId.getId());
}
@Override
public int hashCode() {
return Objects.hash(getId());
}
@Override
public String toString() {
return "UserId{" +
"id='" + id + ''' +
'}';
}
}

get端点的响应:

{
"userId": "8db4c6ab-0872-4688-8cc2-26ea93019f78",
"firstname": "wetryyuf",
"lastname": "dtdddddddf",
"email": "eleanr@waldorf.com",
"profession": null,
"_links": {
"self": {
"href": "http://localhost:8080/v0/api/user/8db4c6ab-0872-4688-8cc2-26ea93019f78"
}
}
}{
"userId": "8db4c6ab-0872-4688-8cc2-26ea93019f78",
"firstname": "wetryyuf",
"lastname": "dtdddddddf",
"email": "eleanr@waldorf.com",
"profession": null,
"_links": {
"self": {
"href": "http://localhost:8080/v0/api/user/8db4c6ab-0872-4688-8cc2-26ea93019f78"
}
}
}

我不知道为什么回复是重复的。

我使用的是Springboot和java 17.

我尝试调用get端点。但是它在我的响应下返回重复的对象,我不知道为什么Spring返回那些畸形的对象。

这个方法似乎被调用了两次。

这是一个调用后的图像。

的端点

的响应输出提示该方法被调用两次。

我应该指定其他端点工作正常。

  1. 一旦与数据库核对,可能同一id被存储两次
  2. 也检查你的实体类和映射如果存在。

这里的方法调用了两次,所以很可能有两个记录具有相同的id。

问题出在我的CustomAuthorization过滤器中。我重新加载了内部过滤器两次,像这样,


@Component
@WebFilter(filterName = "authorizationFilter", urlPatterns = "/*")
public class AuthorizationFilter extends OncePerRequestFilter {
private final AuthenticationUserService authenticationUserService;
private final AuthenticationAssertion authenticationAssertion;
@Autowired
public AuthorizationFilter(AuthenticationUserService authenticationUserService) {
this.authenticationUserService = authenticationUserService;
this.authenticationAssertion = new AuthenticationAssertion();
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (
this.authenticationAssertion.isUnAuthenticateURL(request)
) {
final String header = request.getHeader("Authorization");
try {
if (!authenticationUserService.hasBearerHeader(header)) {
filterChain.doFilter(request, response);
return;
}
final String token = this.authenticationUserService.getAccessTokenString(header);
Token retrievedToken = this.authenticationUserService.retrievedToken(token);
if (!this.authenticationUserService.validateToken(retrievedToken)) {
filterChain.doFilter(request, response);
return;
}
UserDetails userDetails = this.authenticationUserService.loadUserByUsername(retrievedToken.getUsername());
this.setAuthenticationContext(userDetails, request);
filterChain.doFilter(request, response);
} catch (Exception exception) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
Map<String, String> responseBody = new HashMap<>();
responseBody.put("error", exception.getMessage());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(response.getOutputStream(), responseBody);
}
}
filterChain.doFilter(request, response);
}
private void setAuthenticationContext(UserDetails userDetails, HttpServletRequest request) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authenticationToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request)
);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}

通过在else语句中传递doFilter现在工作得很好。

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (
this.authenticationAssertion.isUnAuthenticateURL(request)
) {
final String header = request.getHeader("Authorization");
try {
if (!authenticationUserService.hasBearerHeader(header)) {
filterChain.doFilter(request, response);
return;
}
final String token = this.authenticationUserService.getAccessTokenString(header);
Token retrievedToken = this.authenticationUserService.retrievedToken(token);
if (!this.authenticationUserService.validateToken(retrievedToken)) {
filterChain.doFilter(request, response);
return;
}
UserDetails userDetails = this.authenticationUserService.loadUserByUsername(retrievedToken.getUsername());
this.setAuthenticationContext(userDetails, request);
filterChain.doFilter(request, response);
} catch (Exception exception) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
Map<String, String> responseBody = new HashMap<>();
responseBody.put("error", exception.getMessage());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(response.getOutputStream(), responseBody);
}
} else {
filterChain.doFilter(request, response);
}
}

相关内容

最新更新