I try to access BeanParam, But not possible by my side because to many events access old version jar present on classpath so I can't remove jar files from classpath.
I tried to many way but finally,
I decided create own BeanParam using these links:-
javatpoint |
Annotation_Type_BeanParam_From_Oracle |
Source_code_of_the_class_BeanParam
There are code:-
My BeanParam Interface
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface myBeanParam {
}
My Model Class
import javax.ws.rs.QueryParam;
public class ControllerFilterBean {
#QueryParam("id") String row_id;
#QueryParam("ot") String objectType;
public String getRow_id() {
return row_id;
}
public void setRow_id(String row_id) {
this.row_id = row_id;
}
public String getObjectType() {
return objectType;
}
public void setObjectType(String objectType) {
this.objectType = objectType;
}
}
my resources
public class MyResources {
#GET
#Path("/do/beanTest")
#Produces("application/json")
public Response beanTest(#myBeanParam ControllerFilterBean bean/*
#QueryParam("id") String row_id,
#QueryParam("ot") String objectType*/){
System.out.println(bean.objectType);
System.out.println(bean.row_id);
/*System.out.println(row_id);
System.out.println(objectType);*/
ResponseBuilder rBuild = Response.status(Response.Status.OK);
return Build.type(MediaType.APPLICATION_JSON).entity("OK").build();
}
}
then finally want access my resource class then its throw
WARNING: No message body reader has been found for request
I want help in my code where it's getting mistake.
Related
How to create an aspect class that will implement the logging functionality. Logged classes/packages/methods need to be defined in the configuration file.
#Aspect
public class LoggingAspect {
private static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);
#Autowired
private List<PackageProperties> packageProperties;
#Pointcut("execution(* org.epam.operations.Operations.removeStudentFromList())")
public void removeStudentLog() {
}
#After("removeStudentLog()")
public void applicationLogger() {
log.info("Student deleted");
}
}
application.properties
remove.packageName = org.epam.operations
remove.className = Operations
remove.methodName = removeStudentFromList
add.packageName = org.epam.operations
add.className = Operations
add.methodName = addStudent
For loading the value from properties file you have many ways, which mostly are different in initialization order in IOC container, two of them are as follow
Implement EnvironmentAware interface
public class YourAspectClass implements EnvironmentAware {
private Environment environment;
#Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
Using of #Value annotation to access property .
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface Value {
String value();
}
#Value("#{pointer_of_property}") String value
I have created a custom validator to validate Strings. It works on a single String but not on a List of Strings. This is what I have tried so far:
#Get("/test1")
public String test1(
#QueryValue(value = "ids") List<#DurationPattern String> ids) { //NOT WORKING
return "not working";
}
#Get("/test2")
public String test2(
#QueryValue(value = "id") #DurationPattern String id){ //WORKS
//it does not get here which is what I want.
return "done";
}
My #DurationPattern code:
package my.package;
import javax.validation.Constraint;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import my.package.DurationPattern.List;
#Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE, TYPE, LOCAL_VARIABLE, PACKAGE, TYPE_PARAMETER, MODULE })
#Repeatable(List.class)
#Retention(RUNTIME)
#Documented
#Constraint(validatedBy = { })
public #interface DurationPattern {
String message() default "invalid duration ({validatedValue})";
#Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE, TYPE, LOCAL_VARIABLE, PACKAGE, TYPE_PARAMETER, MODULE})
#Retention(RUNTIME)
#Documented
public #interface List {
DurationPattern[] value();
}
}
Actual Validator:
package my.package;
import io.micronaut.context.annotation.Factory;
import io.micronaut.validation.validator.constraints.ConstraintValidator;
import javax.inject.Singleton;
#Factory
public class MyValidatorFactory {
#Singleton
ConstraintValidator<DurationPattern, CharSequence> durationPatternValidator() {
return (value, annotationMetadata, context) -> {
System.out.println("Please Print!!! It doesn't for Strings within List");
return value == null || value.toString().matches("^PT?[\\d]+[SMHD]{1}$");
};
}
}
Basically, create an implementation of io.micronaut.validation.validator.constraints.ConstraintValidator and provide them inside #Constraint(validatedBy = { })
#Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
#Repeatable(Regexp.List.class)
#Retention(RUNTIME)
#Documented
#Constraint(validatedBy = {DurationPatternValidator.class, DurationPatternValidatorList.class}) //to validate a single string or a list of strings
public #interface DurationPattern {
...
}
#Singleton
public class RegexValidatorList implements ConstraintValidator<DurationPattern, Collection<CharSequence>> {
#Override
public boolean isValid(...) {
....
}
And then in the controller's handler methods you would use
#Get("/test1")
public String test1(
#QueryValue(value = "ids") #DurationPattern List<String> ids) { //#DurationPattern would appear outside of diamond brackets for it to work.
return "working now";
}
I am trying to create an annotation and pass a variable as parameter to the impl method. Below is my code to create an annotation.
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
#Documented
#Target(ElementType.PARAMETER)
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = Loggable1Impl.class)
public #interface Loggable1 {
String message() default "Invalid userId";
}
Below is my impl class
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class Loggable1Impl implements ConstraintValidator<Loggable, String> {
public void initialize(Loggable contactNumber) {
}
public boolean isValid(String generatedUserId, ConstraintValidatorContext cxt) {
System.out.println("generatedUserId in Loggable1 :: " + generatedUserId);
return true;
}
}
I am trying to use it in a spring-boot application
#CrossOrigin(origins = "*", allowedHeaders = "*")
#PostMapping("/api1/{user}")
public Topic regiterUser(#PathVariable String user ) {
String generatedUserId = user + "1";
return generatedUserId ;
}
I want to pass generatedUserId to my annotaion Loggable1
Please assist
I have recently started working on custom Annotations. I created a sample spring boot project where it works fine, but When I try to integrate with my project code, the validation class is not getting invoked.
ValidateField.java
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
#Documented
#Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.TYPE })
#Constraint(validatedBy = { RequestDataValidator.class })
#Retention(value = RetentionPolicy.RUNTIME)
public #interface ValidateField {
String message() default "invalid or value not present";
int revision() default 1;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
RequestDataValidator.java
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class RequestDataValidator implements ConstraintValidator<ValidateField, String>{
#Override
public void initialize(ValidateField constraintAnnotation) {
System.out.println("in Initialize method");
}
#Override
public boolean isValid(String value, ConstraintValidatorContext context) {
System.out.println("in Initialize method");
return (value != null && !value.isEmpty());
}
}
The controller class is as follows.
Please note that the #Valid annotation is used with #RequestBody
import javax.validation.Valid;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.springframework.web.bind.annotation.RequestBody;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
#Api
#Produces({MediaType.APPLICATION_JSON})
#Path("/service")
public interface UIController {
#POST
#Path("/getRules")
#Produces({MediaType.APPLICATION_JSON})
#ApiOperation(
value = "Respond Hello <name>!",
response = Response.class
)
#ApiResponses(
value = {
#ApiResponse(code = 404, message = "Service not available"),
#ApiResponse(code = 500, message = "Unexpected Runtime error")
})
public Response getRules(#Valid#RequestBody SampleRequest discountPromoDetailsRequest);
}
I have checked if the annotation gets applied to the field. Turns out it does. I checked it by using
field.getDeclaredAnnotations()
SampleRequest.java
public class SampleRequest {
private String name;
#ValidateField
private String lastName;
private Long phNum;
private String address;
.
.
//getters and setters of the same.
}
I am now not sure what can be the cause for the RequestDataValidator not getting called.
I am working on this from last 3 days and I still don't have it working in the project.
Any Help is highly appreciated.
I wrote a custom validation to validate an id (Which is a path Param) as UUID in my #GET method of #RestController but this validation doesn't seem to be working. Even during the debug the control doesn't go to custom validation.
#RestController
#RequestMapping("/rateplan")
#Validated
public class RatePlanServiceController {
#RequestMapping(value = "/{ratePlanId}", method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
public void get(#UUID #PathVariable("ratePlanId") String ratePlanId) {
loggerFactory.warn("Get with Rate plan id {}", ratePlanId);
loggerFactory.info("Get with Rate plan id {}", ratePlanId);
loggerFactory.error("Get with Rate plan id {}", ratePlanId);
loggerFactory.debug("Get with Rate plan id {}", ratePlanId);
// return iRatePlanService.getRatePlan(ratePlanId);
}
}
I wrote the custom annotation for validation of UUID as follow.
import org.springframework.stereotype.Component;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
#Target(ElementType.PARAMETER)
#Constraint(validatedBy = {UUID.IdValidator.class})
#Retention(RetentionPolicy.RUNTIME)
public #interface UUID {
String message() default "{invalid.uuid}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
#Component
public class IdValidator implements ConstraintValidator<UUID, String> {
private static final Pattern id_PATTERN =
Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$");
public boolean isValid(String value, ConstraintValidatorContext context) {
if (!(id_PATTERN.matcher(value).matches())) {
return false;
}
return true;
}
public void initialize(UUID parameters) {
}
}
}
Can anyone let me know why is it not working. Even if I provide a garbage ratePlanId like '345%#7^34' it able to go inside GET method.
Solved this by adding a bean in Application configuration file. To validate a path Param in Spring you need to add this bean in your configuration class.
#Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}