Micronaut custom validation Annotation does not work - bean-validation

I was trying to write a custom annotation to validate a field in a Micronaut project, I came across this section in their documentation Defining Additional Constraints
My understanding was that is completely possible to write my own annotation to validate a field in my POJO but after trying for hours, I can't get my validation to work, it simply does not get invoked, could it be I'm missing something fundamental about the way how Micronaut works?
Annotation
#Retention(RUNTIME)
#Constraint(validatedBy = [])
annotation class FieldValidator(
val message: String = "invalid format ({validatedValue})"
)
Factory
#Factory
class ValidatorFactory {
#Singleton
fun fieldPatternValidator(): ConstraintValidator<FieldValidator, CharSequence> {
return ConstraintValidator { value, annotation, context ->
context.messageTemplate("invalid format ({validatedValue}), should be test")
value == "test"
}
}
}
Filter
#Introspected
data class HelloWorldFilter(
#FieldValidator
val field: String?
)
Controller
#Controller("/hello")
open class HelloController() {
#Get("{?filters*}")
#Produces(MediaType.TEXT_PLAIN)
open fun index(#Valid filters: HelloWorldFilter): String {
return filters.toString()
}
}
I have a small demo on Github, to reproduce
run ./gradlew run
call http://localhost:8080/hello?field=abc that expected behaviour should be bad request since the field is matching the desired value.

Using your demo project, I changed your HelloWorldFilter class to
#Introspected
data class HelloWorldFilter(
#field:FieldValidator
val field: String?
)
Ran it, then:
curl "http://localhost:8080/hello?field=abc"
Output was as you expect:
{"message":"Bad Request","_embedded":{"errors":[{"message":"filters.field: invalid format (abc), should be test"}]},"_links":{"self":{"href":"/hello?field=abc","templated":false}}}
With:
curl "http://localhost:8080/hello?field=test"
Output:
HelloWorldFilter(field=test)

Related

ActivatorUtilities.CreateInstance giving "A suitable constructor not found" for simple examples

So I am building a complex case here with inheritance and IOC, need to use ActivatorUtilities to inject instances and pass parameters... no matter what I do I get the following error:
System.InvalidOperationException: 'A suitable constructor for type
'blabla.ISimpleTest' could not
be located. Ensure the type is concrete and all parameters of a public
constructor are either registered as services or passed as arguments.
Also ensure no extraneous arguments are provided.'
So in order to discard what could be the problem and ensure there is no constructor issues, I created a very very simple scenario that gives me the same error.
startup.cs
services.AddScoped<ISimpleTest, SimpleTest>();
the class and the interface, very simple here:
public interface ISimpleTest
{
}
public class SimpleTest : ISimpleTest
{
public SimpleTest()
{
}
}
test
var theInstance = ActivatorUtilities.CreateInstance<ISimpleTest>(ServiceProvider);
Additional notes
The ServiceProvider instance is fine (the rest/entire application depends on it).
Tried with and without adding the public constructor(empty params)
Tried also constructor with params, same error.
Tried to specify the params[] parameter, by sending null or empty array, same issue.
Extra test:
Just to confirm it's properly registered, I tried to get the instance using the Service provider, and works without issues:
//No issues this way:
var yyy = ServiceProvider.GetService<ISimpleTest>();
What am I doing here wrong? According to documentations, this should be enough to work

Kotlin reflection returns incorrect type

I have an activity that implements a listener with a generic type that requires me to implement the onResponse function.
The listener is defined in the following format:
public interface ListenerClass<T> {
onResponse(T type)
}
And my activity implements it using T == ModelClass.
class MyActivity : ListenerClass<ModelClass> {
(...)
override fun onResponse(response: ModelClass) {
(...)
}
}
The listener is part of an SDK so I cannot change any code in there. They use a piece of reflection to get the type of my 'ModelClass' using the following code:
listener.getClass().getDeclaredMethods()[onResponseIndex].getParameterTypes()[0]
The result of this code should be Class<ModelClass> but I get Class<Object>. I found out that when I call the code above on a Java class, I get the correct result, but my activity is written in Kotlin.
1) How can I get the parameter type of a kotlin function using reflection?
2) If I have an answer to question 1 I still won't be able to change the SDK's code. Is there anything I can write in my Kotlin code that makes the piece of code above find the correct parameter class type?

Kotlin reflection on object instance

I've been trying some stuff from kotlin.reflection during my project, and got stuck on something what occurs to me as hard to understand, I have declared object as follows:
object WebsiteMapping
{
const val ADMIN = "/admin"
}
once I call:
Arrays
.stream(WebsiteMapping::class.java.declaredFields)
.forEach { field -> println(field.type) }
what I get is:
class java.lang.String
class mapping.WebsiteMapping
When I looked a little bit into what is behind declaredFields invocation I grasped why it works as it is, but is there any convenient way of taking only declared consts within that object without getting also root of the whole structure?
The field with the type class mapping.WebsiteMapping is, basically, not the root of the structure but a special field generated in the object type that holds the reference to the singleton object.
In Kotlin, this field is named INSTANCE by convention. You can therefore filter the fields that you get from the class as follows:
WebsiteMapping::class.java.declaredFields
.filter { it.name != "INSTANCE" }
.forEach { println(it.type) }
Another solution is to switch from java.reflect.* to the Kotlin reflection API kotlin.reflect (needs a dependency on the kotlin-reflect module), which automatically filters the property:
WebsiteMapping::class.memberProperties
.forEach { println(it.returnType) }

How to render a view from service class in symfony?

I'm trying to make a function in my service class, that render a twig page. I've tried to do like this:
service.yml:
********
parameters:
error.class: AppBundle\Utils\Error
services:
app.error:
class: '%error.class%'
arguments: [#templating]
Error.php (service class):
****
class Error
{
public function __construct($templating)
{
$this->templating = $templating;
}
public function redirectToError($condition,$message)
{
if($condition){
return $this->templating->render('default/error.html.twig',array(
'error_message' => $message,
));
}
}
}
and error.html.twig that have some random text to see if it gets there.
After that I get this answer from browser:
Can somebody to tell me what is the problem?
YAML can be a bit iffy when it comes to syntax, make sure your using all spaces (no tab chars). And makes sure every indentation is the same amount of space characters. Like 2/4/6/8 for each level or 4/8/12 etc if you prefer 4 wide.
The code you posted should be fine, but its probably something silly as described above. If it was actually a wrong section/ parameter in the file symfony should tell you what is unexpected as it actually validates YAML files on its content.
Allright so ['#templating'] takes care of the YAML parse error, the next part is how to use a service. Which is done using the service container.
In a controller there is an alias for it and you can do something like:
// required at the top to use the response class we use to return
use Symfony\Component\HttpFoundation\Response;
// in the action we use the service container alias
// short for $this->container->get('app.error');
$content = $this->get('app.error')->redirectToError(true, 'Hello world');
// as your redirectToError function returns a templating->render, which only returns a
// string containing the the rendered template, however symfony
// requires a Response class as its return argument.
// so we create a response object and add the content to it using its constructor
return new Response($content);
A few small things:
$condition, is probably likely to change if not it seems it should not be in the function but around the function call, as it seems weird to call an redirectToError but there is no error, instead we just call it when we do have an error.
And its recommended to if you are setting a class variable to define it (details on visibility):
class Error {
// visibility public, private, protected
protected $templating;
You should put ' around #templating
services:
app.error:
class: AppBundle\Utils\Error
arguments: ['#templating']

Inheritance and the JSON formatter of ASP.NET Web API

Imagine a simple controller action IEnumerable<BaseType> Get(). It returns an enumeration of different types all deriving from BaseType.
When the client requests XML, the result is something like this:
<ArrayOfBaseType>
<BaseType i:type="DerivedType1"><A>value</A></BaseType>
<BaseType i:type="DerivedType2"><B>value</B></BaseType>
<BaseType i:type="DerivedType3"><C>value</C></BaseType>
</ArrayOfBaseType>
As you can see, the type of the derived class is transmitted in the i:type attribute.
If the client requests JSON however, this information is missing:
[
{"A":"value"},
{"B":"value"},
{"C":"value"}
]
How to fix this?
The following change is necessary:
In the WebApiConfig.cs the following line needs to be added:
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling =
TypeNameHandling.Auto;
This will automatically result in a new property $type when needed.
If you write your class following:
public class MyClass
{
// properties here
public string IType
{
get
{
return this.GetType().Name;
}
set { }
}
}
Maybe, it will help you

Resources