I am trying to validate a request object, whose class is as follows:
#Value
#NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
#AllArgsConstructor
public class SomeCreateRequest {
#NotNull(message = "Name can not be null")
#NotBlank(message = "Name can not be empty")
String name;
}
Without NoArgsConstructor, validation works but POST operation fails with HttpMessageNotReadableException; with NoArgsConstructor, POST operation succeeds but validation doesn't work.
What am I doing wrong?
P.S. using Java 8, Spring 2.3.4.RELEASE, javax.validation 2.0.1.Final and my controller looks like below:
#RequiredArgsConstructor
#RestController
#RequestMapping("/api")
public class MyController {
private final MyService myService;
#PostMapping()
public MyResponse submit(#Valid #RequestBody SomeCreateRequest request){
return myService.create(request);
}
}
Related
I'm using Spring framework,
and I faced the inheritance problem when I write Controller logic.
First of all,
this is my Controller code snippet
#PostMapping("/pay/detail")
public ResponseEntity<PayDetail.Response> getPayDetail(
#Valid PayDetail.Request payDetail
) {
... some code
}
and PayDetail class looks like this
public class PayDetail {
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public static class Request extends CommReqForm {
#NotNull(message = "Not null please")
private String work_type;
}
}
and CommReqForm
#Data
#AllArgsConstructor
#NoArgsConstructor
public class CommReqForm {
#NotEmpty(message = "servicecode not empty")
private String servicecode;
#NotEmpty(message = "reqtype not empty")
private String reqtype;
}
I wish that I can validate both of PayDetail.Request and CommReqForm classes but It makes validation just only PayDetail.Request class.
How can I solve this problem?
#Valid cannot validate super class. I want to make both of sub class and super class validation.
Here is my controller:
#RestController
#RequestMapping("/api/product")
public class ProductController {
#Autowired
ProductService productService;
#PreAuthorize(value = "hasRole('ADD_PRODUCT')")
#PostMapping(value = "/add", consumes = {
MediaType.MULTIPART_FORM_DATA_VALUE,
MediaType.APPLICATION_JSON_VALUE
})
public HttpEntity<?> addProduct(#CurrentUser User user,
#RequestPart("files") MultipartFile multipartFile,
#Valid #RequestPart("info") ProductDto productDto) {
ApiResponse apiResponse = productService.addProduct(user, productDto, multipartFile);
return ResponseEntity.status(apiResponse.isSuccess() ? 201 : 409).body(apiResponse);
}
}
It should receive a MultipartFile and Json object and my ProductDto class is:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class ProductDto {
#NotNull(message = "Name can't be empty")
#NotBlank(message = "Name can't be blank")
private String name;
#Length(max = 1000)
private String description;
#NotNull(message = "Price can't be empty")
private double price;//Evaluated in the $
#NotNull(message = "You should choose one of the categories")
private UUID categoryId;
}
I'm finding difficulties when I try to send request:
But it always giving me 403 Forbidden and I don't know the reason.
This request is not coming to addProduct() method at all and I have permission "ADD_PRODUCT".
#CurrentUser annotation class is:
#Documented
#Retention(value = RetentionPolicy.RUNTIME)
#Target(ElementType.PARAMETER)
#AuthenticationPrincipal
public #interface CurrentUser { }
Not any error or exception is thrown as well.
I have tried #RequestParam and #RequestPart both annotations.
I want to learn how to deal with situations like this when sending MultipartFile and Json object simultaneously.
How can I do that in Spring boot?
The 403 in postman I usually get it when I use http instead of https in the URL. I think you can try editing the postman URL or if that doesn't work try to tell the spring boot app to use simple http.
I have request class for a patch API in the below format
#Schema
#Data
#EqualsAndHashCode(callSuper = true)
#AllArgsConstructor
#NoArgsConstructor
#Builder
public class PricingUsageTemplatePatchInput extends BaseRequest {
#Schema(description = "From node of the Template")
private JsonNullable<#Valid VertexNode> from;
#Schema(description = "To node of the Template")
private JsonNullable<#Valid VertexNode> to;
#NotNull
#Schema(description = "Current version of the template for which update is being made.")
private Long version;
}
VertexNode is as below
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class VertexNode {
#NotNull
#Valid
private Selectors selectors;
#NotNull
#Valid
private Cardinality cardinality;
}
And in the controller layer is as below
#PatchMapping("/{key}")
#Operation(description = "API to update the template")
public PricingUsageTemplateResponse update(#PathVariable #IsUUID final String key,
#Valid #RequestBody #NotNull #Parameter(description = "PricingUsageTemplatePatchInput", required = true)
PricingUsageTemplatePatchInput pricingUsagePatchInput) {
var request = PricingUsageTemplateUpdateRequest.builder()
.key(key)
.pricingUsageTemplatePatchInput(pricingUsageTemplatePatchInput)
.build();
return (PricingUsageTemplateResponse) actionRegistry.get(request).invoke(request);
}
When I am sending selector as null from the postman for the above api , the valid annotation is not able to send valid not null validation error instead I am getting 5xx error with below reason
org.springframework.beans.NotReadablePropertyException: Invalid property 'to.selectors' of bean class [domain.pricing_usage.dto.request.PricingUsageTemplatePatchInput]: Bean property 'to.selectors' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
Can anyone help why #Valid is not working as expected
I want to pass a DTO to Get method:
#GetMapping
public void my_get(MyDto myDto){
}
Above code work's correctly but validations on fields not worked.
#Data
#AllArgsConstructor
#NoArgsConstructor
public class MyDto {
#NotNull
#NotBlank(message = ValidateConstant.NOT_BLANK_MESSAGE)
String id;
String uri;
String type;
String version;
}
I'm also add #Valid annotation but also Get method return 200 in response.
add #Valid annotation
public void my_get(#Valid MyDto myDto){
if that does not help, add #Validated at the class level.
I have created a spring boot application. And in the application I'm working with API's. I have an POST API for creating an user, but every time I use the api, i will get the following error
Spring boot post api - org.postgresql.util.PSQLException: ERROR: null value in column "password" violates not-null constraint
Im using hibernate and PostgreSQL as database.
Even if I give de data values, i will get this error. I searched over the internet, but I cant find a solution for this problem
This is the code that i user:
Users.java:
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#Builder(toBuilder = true)
#ToString
#Table
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int user_id;
#Column(unique = true, nullable = false)
private String username;
#Column(nullable = false)
private String password;
}
UsersRepository.java
#Repository
public interface UsersRepository extends JpaRepository<Users, Integer> {}
UsersService
#Service
#RequiredArgsConstructor
#Transactional
public class UsersService {
private final UsersRepository usersRepository;
public Users createUser(Users newUsers) {
return this.usersRepository.save(newUsers);
}
}
UsersDto
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class UsersDto {
private int user_id;
private String username;
private String password;
}
UsersMapper
#Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UsersMapper {
UsersDto toDto(Users users);
Users toModel(UsersDto usersDto);
}
UsersController
#RestController
#CrossOrigin(origins = "http://localhost:4200")
#RequiredArgsConstructor
#RequestMapping("/users")
#Validated
public class UsersController {
private final UsersService usersService;
private final UsersMapper usersMapper;
#PostMapping()
#ApiOperation(value = "Create new user", httpMethod = "POST", code = 201)
#ResponseBody
public ResponseEntity<UsersDto> createUser(#RequestBody UsersDto usersDto) throws Exception {
Users users = this.usersMapper.toModel(usersDto);
Users createUsers = this.usersService.createUser(users);
return ResponseEntity.ok(this.usersMapper.toDto(createUsers));
}
}
I hope someone can help me with this problem
The error says that the password is null, what is not allowed. So it's probably not provided on the request send to your API. You could add validation constraints to the endpoint, like
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class UsersDto {
private int user_id;
#NotNull
private String username;
#NotNull
private String password;
}
One more note, storing password as plain text is not advised , it's a major security issue. You should create and use a hash instead, check out Spring Security for this.
PS - check out bootify.io - here you can create your REST API together with the validation constraints.