Approach: Modify Complex Data using AOP and Reflection - java

I have configured my spring Application as below:
// Spring MVC controller
#Controller
HelloController {
#ResponseBody
Student getData() {
return student from database;
}
}
public Class Student {
#Trim(device = "mob", trim=10)
#Trim(device = "desktop", trim=100)
String name ;
Address address;
}
public class Address {
#Trim(device = "mob", trim=10 )
#Trim(device = "desktop", trim=100 )
String addressInfo
}
Requirements:
After the Controller returns the Student, do modification of Student object and all complex attributes inside it based on the Annotation,
for example if the request was from mobile trim the student name to 10 and so on.
Approaches I can think of:
Recursively iterate on fields with annotation and modify fields.
Iteration on class fields every time can be hectic, as the class is complex and can nest up to n levels.
Create a List of Annotated fields at server start up and when then iterate on this list and apply changes to the target object.
I am currently struggling with both approachs. So would like to know whether there exists some prebuilt solutions or design patterns to handle such scenarios.

I actually coded the Reflection based approach and created a library some time back.
It uses reflection to identify annotation on fields and then takes the appropriate action based on the input device.
Here is the link for library
https://github.com/santoshjoshi/Adaptive-Device-Data-Filtering

Related

Creating JsonLd + Hydra based Generic Client API in java. Is there any projects exist for reference?

I am creating Client API in Java using :+ Apache Jena FrameWork+ Hydra(for Hypermedia driven) + my private vocab similar to Markus Lanther Event-API Vocab instead of schema.org(for Ontology/Vocabulary part)
Section 1 :
After looking this Markus Lanther EventDemo repo and hydra-java.I found that they are creating classes for each hydra:Class that can break client in future .For example :
A Person class (Person.java)
public class Person
{
String name;
};
But in future requirement name is also a class eg:
public class Name
{
String firstName;
String LastName;
};
So to fulfill this requirement I have to update Person class like this:
public class Person
{
Name name;
};
Question 1:
Is my understanding correct or not of this Section? If yes then what is the way to deal with this part ?
Section 2:
To avoid above problem I created a GenericResource class(GenericResource.java)
public class GenericResource
{
private Model model;
public void addProperty(String propertyName,Object propertyValue)
{
propertyName = "myvocab:"+propertyName;
//Because he will pass propertyName only eg: "name" and I will map it to "myvocab:name"
//Some logic to add propertyName and propertyValue to model
}
public GenericResource retriveProperty(String propertyName)
{
propertyName = "myvocab:"+propertyName;
//Some logic to query and retrieve propertyName data from this Object add it to new GenericResource Object and return
}
public GenericResouce performAction(String actionName,String postData)
{
//Some logic to make http call give response in return
}
}
But again I stuck in lots of problem :
Problem 1: It is not necessary that every propertyName is mapped to myvocab:propertyName. Some may be mapped to some other vocab eg: hydra:propertyName, schema:propertyName, rdfs:propertyName, newVocab:propertyName, etc.
Problem 2: How to validate whether this propertyName belongs to this class ?
Suggestion: Put type field/variable in GenericResource class.And then check supportedProperty in vocab corresponding to that class.To more clarity assume above Person class which is also defined in vocab and having supportedProperty : [name,age,etc] .So my GenericResource have type "Person" and at time of addProperty or some other operation , I will query through vocab for that property is in supportedProperty list or in supportedOperation list in case of performAction().
Is it correct way ? Any other suggestion will be most welcomed?
Question 1: Is my understanding correct or not of this Section? If yes
then what is the way to deal with this part ?
Yes, that seems to be correct. Just because hydra-java decided to creates classes doesn't mean you have to do the same in your implementation though. I would rather write a mapper and annotate an internal class that can then stay stable (you need to update the mapping instead). Your GenericResource approach also looks good btw.
Problem 1: It is not necessary that every propertyName is mapped to
myvocab:propertyName. Some may be mapped to some other vocab eg:
hydra:propertyName, schema:propertyName, rdfs:propertyName,
newVocab:propertyName, etc.
Why don't you store and access the properties with full URLs, i.e., including the vocab? You can of course implement some convenience methods to simplify the work with your vocab.
Problem 2: How to validate whether this propertyName belongs to this
class
Suggestion: Put type field/variable in GenericResource class
JSON-LD's #type in node objects (not in #value objects) corresponds to rdf:type. So simply add it as every other property.
And then check supportedProperty in vocab corresponding to that class.
Please keep in mind that supportedProperty only tells you which properties are known to be supported. It doesn't tell you which aren't. In other words, it is valid to have properties other than the ones listed as supportedProperty on an object/resource.
Ad Q1:
For the flexibility you want, the client has to be prepared for semantic and structural changes.
In HTML that is possible. The server can change the structure of an html form in the way outlined by you, by having a firstName and lastName field rather than just a name field. The client does not break, rather it adjusts its UI, following the new semantics. The trick is that the UI is generated, not fixed.
A client which tries to unmarshal the incoming message into a fixed representation, such as a Java bean, is out of luck, and I do not think there is any solution how you could deserialize into a Java bean and survive a change like yours.
If you do not try to deserialize, but stick to reading and processing the incoming message into a more flexible representation, then you can achieve the kind of evolvability you're after. The client must be able to handle the flexible representation accordingly. It could generate UIs rather than binding data to fixed markup, which means, it makes no assumptions about the semantics and structure of the data. If the client absolutely has to know what a data element means, then the server cannot change the related semantics, it can only add new items with the new semantics while keeping the old ones around.
If there were a way how a server could hand out a new structure with a code-on-demand adapter for existing clients, then the server would gain a lot of evolvability. But I am not aware of any such solutions yet.
Ad Q2:
If your goal is to read an incoming json-ld response into a Jena Model on the client side, please see https://jena.apache.org/documentation/io/rdf-input.html
Model model = ModelFactory.createDefaultModel() ;
String base = null;
model.read(inputStream, base, "JSON-LD");
Thus your client will not break in the sense that it cannot read the incoming response. I think that is what your GenericResource achieves, too. But you could use Jena directly on the client side. Basically, you would avoid unmarshalling into a fixed type.

Design patterns - How to enforce object attributes only in some situations (Builder pattern, Dependency Injection)

I am in a very particular situation with one of the classes I'm coding. I have this class called User that looks like this:
public class User {
private long id; // + getters and setters
private boolean isDeletable; // + getters and setters
private String name; // + getters and setters
private String password; // + getters and setters
private String email; // + getters and setters
private String authenticationRealm; // + getters and setters
private String displayName; // + getters and setters
private Date deletedDate; // + getters and setters
}
Within my code there are several situations where I just need an empty object of the type User and therefore just build it using the default constructor: new User().
However, I have another class called CreateUserRequest which models a REST request to create the user in a server. The minimum payload must contain the name, password, email, and authenticationRealm attributes sent in JSON format.
Right now I am handling this by checking for these parameters in the constructor of the request:
public CreateUserRequest(User user) {
if(user.getName() == null || user.getPassword() == null || user.getEmail() == null || user.getAuthenticationRealm() == null)
throw new RuntimeException("Not enough attributes in User object. Minimum: name, password, e-mail and authentication realm.");
}
This is working OK but something is itchy... I would like to enforce this in a safer way, so that the code would enforce the attributes to be populated with no possibility of an exception being thrown.
I feel like there must be a better way to do this with a design pattern. I thought of creating a UserRequestBuilder class, but that would also possibly imply throwing an exception in the build() method (otherwise, is there a way I can guarantee that the attributes are populated before build()?). Dependency injection also sounds like a possibility, but I'm not sure how I would put it in place in this particular example...
Any thoughts?
How about making your REST services operate on a UserDTO? (Off course, the UserDTO could be replaced with a subclass of User).
You could annotate the fields, setters or constructor parameters on the UserDTO with #NonNull and have the Checker Framework issue compiler warnings when passing null values instead of name password, email etc to the UserDTO.
Using a framework like Mapstruct, mapping between the REST services DTOs and the backend objects is very easy:
#Mapper
public interface UserMapper {
public static final UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserDTO map(User user);
User map(UserDTO userDTO);
}
Above code will upon compilation generate a UserMapper implementation, with autogenerated code for the specified methods ( - and the autogenerated code simply pairs similarly named getters and setters. You could do this yourself, but with many DTOs/Entities is becomes time consuming and boring).
In the DTOs you could exclude all those fields you do not want to expose.
Ps. My own usage of above mentioned is this: I am creating a REST server based on Jersey, i.e. the reference implementation of JAX-RS. This project, call it A, only knows about the DTOs. The REST methods calls into another project B, which retrieves the objects from database, and maps them to the corresponding DTO, which is then returned to project A. Part of the reason for this pattern is that the entities of project B for historical reasons are cluttered with methods/functionality, which should not be exposed to project A. As for the sanity checks (JSON to DTO), jersey supports Bean Validation, which is to say, that the framework will validate each rest resource's input beans if they are annotated with #Valid.
It is also possible to create your own custom annotations, which have a ConstraintValidator defined. The bean validation framework will check these constraints on the annotated jersey REST method parameters.
See https://jersey.java.net/documentation/latest/bean-validation.html#d0e13690
I came up across a similar problem , I came up with the solution of adding a Custombuilder with constructor having arguments. So it ensures that i am ensuring that client(user) has to provide those credentials for building that object
class UserRequestBuilder{
public UserRequestBuilder(String name,String password,String email,String authenticationRealm){
// set values here
}
}

Best way to pass a POJO to a spring MVC controller

I have done a few MVC controllers now and used the spring form tags to pass data back and forth but I realise now my actual understanding is a little thin. In my current case I could actually just send the response as url parameters but there are about 15 and I would prefer to send it as a pojo if possible.
My actual question... is ... is it possible to set up a spring style model attribute in a jsp without the attribute having been passed in and without using the form tags ?
So for example something along the lines of
//Pojo
Class personclass
{
private String name + getters and setters
private String address + getters and setters
private String phone + getters and setters
...
}
////first mvc call
#RequestMapping ("/")
Public ModelAndView LandingPage()
{
// no mention of Person pbject
Return mandvobject;
}
//jsp page
//This is the question!
SET ModelAttribute that wasn't passed in to the page
personclass = X
//New MVC call without a submit
window.open ("/NewMVCCall")
//New mvc call
#RequestMapping ("/NewMVCCall")
Public void newMVCPage(#ModelAttribute ("pc") personclass pc, Model model)
{
//process pc object
}
Or am I missing the point and I would have to send it as a json string parameter? Sorry my grasp of this is pretty rudimentary and I'm not sure whether I could quite easily set my own http form content or whether it is because I have used Spring form objects so far that I haven't grasped the complexity of what is going on behind the scenes (i.e form tags converting pojos to json and so on) ?
Many thanks if anyone has the time to set me on the right path...
I am not sure if I am understood your question correctly but you can link a Model to your controller without having to manually pass it to a the view every time you need it, spring will take care of that:
in your Controller :
public class MyController{
#ModelAttribute("pc")
public PersonneClass getPersonnelClass(){
return new PersonneClass();
}
#RequestMapping ("/NewMVCCall")
Public void newMVCPage(#ModelAttribute ("pc") personclass pc, Model model)
{
//process pc object
}
//other methods
}
It is a good practice to stick to java conventions when naming classes so
(personneClass ) must start with an uppercase (PersonneClass) .

Architecture for building XML requests?

I'm writing a client tool that uses soap xml webservices (using CXF to autogenerate the classes from provided wsdl). I wonder which design is best to construct the xml requests I want to sent to the webservices. My problem is that the request to be send has to be formed of many different parts/objects. I'm looking for a clean way of how to structure the creation of these parts, that finally form the full request.
The request might be growing to 200-500 XML lines, so it is probably a bad idea to create these all in a single class.
To illustrate my goal, let's assume a request requires a Person object, and some params have to be set on that object like name, birthday, address etc. I could think of the following designs:
1) static utility that returns the constructed xml part
class XMLUtil {
public static PersonType createPerson(String name, String birthday, Address Address) {
//the xml person to send within the request
PersonType p = new PersonType();
p.setName(name);
p.setBirthday(birthday);
p.setAddress(address);
//assume some more params, but the concept is clear I hope
return p;
}
}
2) static utility that adds the constructed xml part to the xml request
class XMLUtil {
public static void addPerson(WebserviceReq req, String name, String birthday, Address Address) {
//create person as above
req.addPerson(p);
}
}
3) non static service
class XMLService {
private WebserviceReq req;
public XMLService(WebserviceReq req) {
this.req = req;
}
public void createPerson(String name, String birthday, Address Address) {
//create person as above
req.addPerson(p);
}
public WebserviceReq getWebserviceReq() {
return req;
}
}
usage:
1)
WebserviceReq req = new WebserviceReq();
req.addPerson(XMLUtil.createPerson("test", "2014-01-01", address));
req.send();
2)
WebserviceReq req = new WebserviceReq();
XMLUtil.addPerson(req, "test", "2014-01-01", address);
req.send();
3)
WebserviceReq req = new WebserviceReq();
XMLService service = new XMLService(req);
service.createPerson("test", "2014-01-01", address);
service.getWebserviceReq();
req.send();
Which approach would you prefer if there is not only a person object to be constructed for the xml request, but lots of more parts that you are trying to encapsulate somehow, so that not a single class is blowing up?
What I have done and used many times to great effect is the following...
Create a set of classes for each of the element types in XML - this to include the following...
Node - Base class for all elements. Supports setting and getting of attributes.
Leaf - base class for any element containing a value (simple elements)
Branch - a collection of Leaf elements. Children are accessed by index.
Entity - A Branch that allows keyed access to its children.
As opposed to how you are doing it now, where you have a bean named Person which has private variables and requires code to set and get each value, you would use an Entity instance and add leaf instances to it, for example...
Entity person = new Entity("Person");
person.add(new Leaf<String>("FirstName", "Rodney"));
person.add(new Leaf<String>("LastName", "Barbati"));
The power here comes from adding the ability of the base classes to write themselves out as XML. This gives you the ability to quickly create new types and not have to write code to convert them to XML.
You can also make this completely transparent by deriving the person class from Entity and adding the child elements in its constructor. I would also advise you to add a validation method that checks for the existence and correct formatting of each required child.
There are classes provided in Java for dealing with XML elements but they are somewhat cumbersome and not easily used. You could consider either wrapping them or deriving from them to make them more easily used.
The above gives you the ability to output XML easily without requiring boilerplate code - if you marry it with a custom SAX parser that can construct a given class for a given element, you have a complete basis for high speed, streaming XML services that can support new data types almost instantly with very little lines of code - often none at all.
If you find yourself writing custom code to output any XML structure, understand that you don't have to - there is a better solution.
BTW: The above classes would lend themselves quite nicely to defining the data structures in Spring.
Good Luck,
Rodney Barbati

Where to validate String parameter

I have a Student class that has to have a property of a String ID, which has to be validated. I'm not sure whether to validate it inside the student class or the class that I'm implementing the Student class in. Does that make sense?
Assuming ID is final and immutable, then one approach is to have Student constructor throw an exception, probably new IllegalArgumentException("Invalid student ID");
You may additionally provide static method in Student class, which verifies if string is valid, in case you need to check it without creating Student object.
But the logic of determining if ID is valid or not should be in the Student class, I think.
If there are (or can be in future) different kind of student IDs, you could also consider abstract factory pattern, but sounds like that is bit of an overkill.
If Student already has any business inside use validate inside else use second one
Class Student
{
public boolean validate ()
{
//some logic to validation
}
}
Inside of Model or controller or Action
public boolean validate ()
{
//some logic to validation
}
One of the approach is to use validation object. For instance see the Validation approach uses in the Spring Framework. You create an object which implements the interface Validator with two methods: one to detect if the Validator can validate the instance to validate, and another one which validate it.
public class StudentValidator implements Validator<Student> {
public boolean supports(Student student) {
// ...
}
public void validate(Object target, Errors errors) {
// ...
}
}
This approach leads to separation of the code of the object and the way to validate it, offering more flexibility when combining validator:
you can combine several Validator even if the class hierarchy is not respected (POJO principle).
when you need to validate field with data from other system (for instance a database), this approach avoid to mix database / persistence code in the POJO domain class.
Please see the documentation of Spring about Validation.

Categories