Resteasy mapping #PathParam and #QueryParam to Pojo - jax-rs

I want to reduce my lines of code in a restful ws. My service is :
#GET
#Path("/acc_bloq/{unit}/{id}/search")
#Produces("application/json")
public FiltroBean getAcc_Bloq(#PathParam("unit") String unit,
#PathParam("id") int id, #QueryParam("init") int init, #QueryParam("end") int end){}
Is there any way to mapping directly the parameters to a POJO? so to save lines of code
Filter filter = new Filter()
filter.set....
filter.set...
Thanks in advance.

I think that #BeanParam is what you are looking for.
The annotation that may be used to inject custom JAX-RS "parameter aggregator" value object into a resource class field, property or resource method parameter.

Related

Field level access Control using Aspects/ Custom Annotation (Spring boot , Microservice)

Currently i am trying to implement authorization on fields , please find the cases from the below
example :
Based on some specific roles which are available in the ThreadLocal , we should be able to determine whether the user is allowed to pass the field in the payload. if the received role is not allowed to pass the attribute to do any Creation or updation we should throw 403
While providing response in the GET API , we should hide few fields which all are annotated with role:"ADMIN" as an example .
For the above example i am trying to use custom annotation Target as Fieldex :
#Documented
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface CustomScopeFilter {
String[] scopesAllowed() default {"END_USER"};
}
But the custom annotation with FIELD is not working actually , because the implementation class which annotated with #Aspect is not getting called
The above annotation i have used in my DTO on field level
ex :
#Getter
#Setter
class TestDTO {
#CustomScopeFilter(scopesAllowed={"ADMIN"})
private String userRole;
}
Any ideas or suggestion would be very much helpful !! Thanks in advance
tried using Pointcut , joinpoint ,Aspectj, AOP. but those didnot worked on field-level
So i am expecting some suggestions how i can make it work .. or any alternative approach to achieve the same.

Id Encryption in spring-hateoas or Spring Rest Data

I have a question about a standard pattern or mechanism in spring-hateoas or Spring Rest Data about encrypting the IDs of the Resources/Entities.
The reason I am asking, a requirement to our project is that we don't deliver the id's of our objects to the outside world and they should not be used in GET Requests as Parameters.
I know, Spring Rest Data and spring-hateoas does not give the ids of the objects unless they are configured so but even that case I can see the ids in links.
I know I can use PropertyEditors or Converters to encrypt/decrypt ids before and after Json serialisation/deseritalisation but I just like to know is there a more standard way?
Thx for answers...
If you have the unique 'business id' property of your resource you can configure SDR to use it instead of the entity ID.
First you have to create lookup method of your entity with this unique property:
public interface MyEntityRepo extends JpaRepository<MyEntity, Long> {
#RestResource(exported = false)
Optional<CatalogResource> findByMyUniqueProperty(String myUniqueProperty);
}
Then use it to configure SDR:
#Component
public class DataRestConfig extends RepositoryRestConfigurerAdapter {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.withCustomEntityLookup()
.forRepository(MyEntityRepo.class, MyEntity::getMyUniqueProperty, MyEntityRepo::findByMyUniqueProperty);
super.configureRepositoryRestConfiguration(config);
}
}
After this customization you will have resource URI like this:
http://localhost:8080/myEntities/myUniquePropertyValue1

findBy URI not working in Spring Data Rest

By default, in Spring Data Rest the #Id of the entity is not exposed. In line with the REST rules, we're supposed to use the URI of the resource to refer to it. Given this assumption, the findBy queries should work if you pass a URI to them, but they don't.
For example, say I have a one-to-many relationship between Teacher and Student. I want to find students by teacher.
List<Student> findByTeacher(Teacher teacher)
http://localhost:8080/repositories/students/search/findByTeacher?teacher=http://localhost:8080/repositories/teachers/1
This doesn't work because the framework is attempting to convert the teacher URI to a Long.
I get this error that says "Failed to convert from type java.lang.String to type java.lang.Long".
Am I missing something?
You could expose #Id s by configuring web intializer
//Web intializer
#Configuration
public static class RespositoryConfig extends
RepositoryRestMvcConfiguration {
#Override
protected void configureRepositoryRestConfiguration(
RepositoryRestConfiguration config) {
config.exposeIdsFor(Teacher.class);
}
}
Its good to change List to Page
List findByTeacher(Teacher teacher)
to
Page<Student> findByTeacher(#Param("teacher) Teacher teacher, Pageable pageable);
Also note #Param annotation is required along with Pageable. The latter is required because return type "Page"
3.Latest snapshots, not milestones work fine
See https://jira.spring.io/browse/DATAREST-502
Depending of your version of Spring Data, it would work as you want or not. If you are with Spring Data 2.4, you need to pass the URI. If you are with a previous version, you need to pass the id.

How can I resolve dependency in Castle Windsor Factory?

I read about factories in CastleWindsor but I cannot get it clear. Hope anyone could help me.
I have this typed factory in an MVC4 project.
public interface IOrderProcessorFactory
{
T Create<T>(string ProcessorName) where T : IOrderProcessor;
void Release(object service);
IOrderProcessor GetTakeAway();
IOrderProcessor GetInLocal();
}
this is register this way:
container.Register(Component.For<IOrderProcessorFactory>).AsFactory();
container.Register(Component.For<IOrderProcessor>).ImplementedBy<TakeAwayOrderProcessor>().LifestylePerWebRequest().Named("TakeAway"));
container.Register(Component.For<IOrderProcessor>().ImplementedBy<InLocalOrderProcessor>().LifestylePerWebRequest().Named("InLocal"));
If inside an MVC controller I call the factory in this way.
_orderProcessorFactory.GetTakeAway();
I get the correct one, the one named "TakeAway".
But for this I have to previous know the type. In other words, I want to call the factory get methods and pass a "name" and the factory returns the correct one.
For example in pseudo-code I want this
TakeAwayOrderProcessor processor1 = factory.GetMeProcessorCalled("TakeAway")
InLocalOrderProcessor processor2 = factory.GetMeProcessorCalled("InLocal")
I know I can pass parameters to the constructor but then I will have to select it "manually" with if name is this return this one else...
Is there any way Windsor can do this automatic, like StructureMap do with:
ObjectFactory.GetNamedInstance<IOrderProcessor>("InLocal");
You need a TypedFactoryComponentSelector

Replace WCF default JSON serialization

Is it possible to replace the default JSON serialization of WCF (I'm currently testing with the webHttp behaviour), and passing application/json as the MIME type. In particular, I don't like that by default every property is a key/value pair like:
{"Key":"PropertyName", "Value":"PropertyValue"}
I'm using the service only for JSON-enabled endpoints (requesting data with jQuery + WCF).
You can use a message formatter to change the serializer used to deal with JSON. The post at https://learn.microsoft.com/en-us/archive/blogs/carlosfigueira/wcf-extensibility-message-formatters shows an example on how to change the default serializer (DataContractJsonSerializer) to another one (JSON.NET).
Consider creating classes corresponding to your JSON object structure. In that case you don't have to use Dictionary<> like:
[DataContract]
public class Customer
{
[DataMember(Name="name")]
public string Name{get;set;}
[DataMember(Name="id")]
public int ID{get;set;}
}
This get serialized as:
{"name": "name-value", "id": "id-value"}
Of course, this is just an alternative to what you already have and may not be applicable.