some strange issue has shown up, in the business model I use list of addresses that cannot be empty or null, but each field in the object address cannot be null or empty either. But when I send a request with one of the fields empty, the request will pass to the repository, which shouldn't happen. Instead of passing a request, the server should return an internal server error.
Address object:
@Data
@NoArgsConstructor
public class Address {
@NotEmpty(message = "Street may not be empty")
@Size(min = 2, max = 256)
private String street;
@NotEmpty(message = "Number may not be empty")
@Size(min = 1, max = 5)
private String number;
@NotEmpty(message = "Postal code may not be empty")
@Field("postal_code")
@JsonProperty("postal_code")
@Size(min = 5, max = 6)
private String postalCode;
@NotEmpty(message = "City may not be empty")
@Size(min = 2, max = 256)
private String city;
@NotEmpty(message = "Province may not be empty")
@Size(min = 2, max = 256)
private String province;
@NotEmpty(message = "Country may not be empty")
@Size(min = 2, max = 256)
private String country;
}
Business object which contains list of addresses:
@Data
@NoArgsConstructor
@Document(collection = "businesses")
public class Business {
@Id
private String id;
@NotBlank
@Size(max = 64)
private String name;
@Field("created_at")
private Date createdAt;
@Field("updated_at")
private Date updatedAt;
private Boolean active;
@DBRef
private User owner;
private List<Address> addresses;
public Business(String name, User owner, List<Address> addresses, Date createdAt, Date updatedAt, Boolean active) {
this.name = name;
this.owner = owner;
this.addresses = addresses;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.active = active;
}
public Business(String name, User owner, List<Address> addresses, Date updatedAt, Boolean active) {
this.name = name;
this.owner = owner;
this.addresses = addresses;
this.updatedAt = updatedAt;
this.active = active;
}
}
And in the end, service:
@Override
public ResponseEntity<?> createBusiness(CreateBusinessRequest request, String token) throws RuntimeException {
Optional<User> user = userRepository.findByUsername(jwtUtils.getUserNameFromJwtToken(token.substring(7)));
if(businessRepository.existsByName(request.getName())) {
throw new ItemAlreadyExistsException("Business with " request.getName() " already exists!");
}
if(user.isEmpty()) {
throw new NotFoundException("User with " user.get().getUsername() " does not exist!");
}
if(request.getAddresses().isEmpty() || request.getAddresses() == null) {
throw new InvalidInputException("Address is empty!");
}
Business business = new Business(
request.getName(),
user.get(),
request.getAddresses(),
new Date(),
new Date(),
true
);
businessRepository.save(business);
return ResponseEntity.ok(business);
}
Controller:
@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
@PostMapping("/create")
public ResponseEntity<?> createBusiness(@Valid @RequestBody CreateBusinessRequest request, @RequestHeader (name="Authorization") String token) {
return businessService.createBusiness(request, token);
}
Request:
{
"name": "Test business",
"addresses": [
{
"street": "",
"number": "100",
"postal_code": "84104",
"city": "Test city",
"province": "Test",
"country": "Slovakia"
}
]
}
I hope that I explained my issue correctly. Is there any solution to this issue?
Thanks in advance.
CodePudding user response:
Per this question I recommend adding the @Valid annotation (javax.validation.Valid) to the addresses property of the Business class. Also see the example here
CodePudding user response:
My guess is that you are missing one key dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
CodePudding user response:
To fully configure method level security you need to add the following annotation/class:
@Configuration
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}
This will turn on validation of your service methods. As mentioned earlier, you can add BindingResult to your controller and check for errors in the controller if needed.