Spring MVC Controller common logic - json

I am trying figure out best possible way to write a common logic in Spring MVC application. I have a Controller A which would be called which would invoke any another Controller based on request attributes which return json data.
I want the response back in controller A so that i can write common enrichment logic and send it back to browser. My intent is write enrichment logic only at one place and every request goes through it.

What your are looking for are so called HandlerInterceptor or ControllerAdvice.
I made a small repository on Github about Spring MVC Interception a while ago, it is a small Spring Boot application, which is showing you the ways to intercept a request with Spring MVC.
The question is always what is your main goal:
Do you want to just manipulate the output (e.g. adding a common field)? Use ControllerAdvice.
Do you want to call a logic before and after, without manipulating the request? Go for filters.
Do you want to change the object fundamentally (e.g. wrap it with another object)? Go for HandlerInterceptor.

May be you can create abstract controller class and put the common logic or code in it. So wherever you want to use this common code just extend this class and use it.
For example :
public class AbstractController{
// common logic
}
public class A extends AbstractController{}
public class B extends AbstractController{}
public class C extends AbstractController{}

Related

How to define custom handling for a response class in Spring doc?

I've been using arrow-kt and spring together a lot lately. I've actually constructed a bridge between the two with several key features, one of which is a spring controller that returns an Either will automatically unwrap it and either handle the exception (Left) or return the result (Right). My long term goal is to publish this as a library.
My latest obstacle is Swagger, or more accurately springdoc openapi. Obviously it is seeing the Either, but i want it to show only the Right value as the success response type. While I know there are annotations where I can set the response model on each controller method individually, I'm trying to avoid this.
My real goal is to setup some global converter so that wherever Swagger sees an Either it will automatically unpack this. I'm just not super familiar with the customization API in Spring doc, and everything I Google just points me to the ApiResponse annotation solution.
How can I define default handling for this type of response?

Spring MVC #RequestBody and partial object/json binding

I have a large object which can be updated in a few steps. I'am facing a partial binding problem. My service consumes json and I can not use #InitBinder along with #RequestBody. Cutting this object to a few small ones is not good a solution, because there is a lot of cross-field validations between steps.
Do you have any ideas how to solve this? I'am looking for a clean solution like: registering a specific object mapper for given #RequestMapping or something like that. Thanks for help.
You should be able to use a PATCH HTTP method
Its the preferred method that you would use when you need partial updates, like in your case when you want to update just a few fields of a resource
Spring MVC added a support for it in the version 3.2, so you can do something like
#RequestMapping(value="/patch", method=RequestMethod.PATCH, consumes=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String patch(#RequestBody Foo foo) {
return foo.toString();
}
and when sending the request, add only the properties you want to update to your PATCH request, the properties that are null or omited won't be updated
In the lack of better Spring MVC PATCH reference, I'm linking this SO thread as an interesting read Spring MVC PATCH method: partial updates

how to bind HTTP POST data to python object in Django Rest Framework?

I will give an example to better explain my question
my request:
POST
http://localhost:8080/users/
request body: (This gets posted)
{"name":"Matt",
"salary":10000,
"blog_url":"www.myblog.com",
"dept_name":"ENG"
}
class CustomRequest(object):
def __init__(self,name,salary,blog_url,dept_name):
self.name=name
self.salary=10000
self.blog_url=blog_url
self.dept_name=dept_name
models.py
class myUser(models.Model):
//fields -- username, salary
class myUserProfile(models.Model):
User=models.OneToOneField(user)
blog_url=models.URLfield()
dept_name=models.ForeignKey(Department)
#apiview(['POST'])
def createUser(customrequest):
myuser=user(customrequest.name, customrequest.salary)
myuser.save()
myuser.userprofile.blog_url(customrequest.blog_url)
myuser.userprofile.dept_name(customrequest.dept_name)
myuser.save()
I have been most of REST services using Java JAX-RS API. In this framework,
POST request body is automatically deserialized to the object that the method takes in( in the above example, it is customrequest). A developer can define an object with attributes that he is looking for in the POST request and then perform the business logic.
Now that we are thinking of migrating to Django, I am wondering if Django Rest Framework provides this kind of behavior out of box. If so, how would I do that?
Please note, in the JAX-RS world, there is no need for a developer to write a serializer. All that is needed is the transfer object where the incoming JSON gets deserailzed into.
I assume in Django, both a serializer and a transfer object is needed to achieve the same purpose.
In DRF, you have two options:
either you use ModelSerializer and you get the model instance automatically
or you use Serializer and you get the validated_data and do whatever you like with it
The serializer is the same as what you call transfer object, in the sense that both define the data structure and that both will hold the deserialized values.
For models, it is required for persistence, but that is also required in JAX-RS, unless you use the same classes as ORM entities(which is a bad design). So in JAX-RS you will have, for example, CustomRequest and JPA CustomRequestEntity

JSON Objects vs Spring Model Objects

I am using standard Spring MVC 3x framework and have my model entities all built up with all the good relational stuff (javax.persistence API)... integrated with my DB.
As the application evolved, we needed to support JSON calls.
Given that I have various relationships mapped out in my Model Entity layer,
(classX->classY as well as classY->classX)
I am wondering what the best practice is in translating some of these model classes to appropriate JSON objects without duplicate re-referencing?
eg: Sample buggy response
{"classX":{"id":"1", "classY":{"id":"2", "classX":{"id":"1", "classY":{"id":"2"...
I am contemplating a couple of methodologies I wouldn't mind feedback on...
Keep the existing model classes and set the cross relationships to NULL before putting it into my ModelMap so there won't be some form of re-referencing (me thinks its a HACK)
{"classX":{"id":"1", "classY":{"id":"2", "classX":null}}}
Recreate JSON classes similar to the existing models without the re-referencing classes (but I think that means they will not be as reusable... since I will end up only having classX->classY and not backwards if I wished to drill the other way for a data response).
{"jsonClassX": {"id":"1", "jsonClassY":{"id":"2"}}}
Just simply construct it as standard ModelMap mappings for every controller call. As such no concept of a reusable JSON class, and is dependent on the way the controller constructs and organises the return values. This seems like the easiest, but it means no-reusable code (besides cut and paste)...
{"x":{"id":"1", "y":{"id":"2"}}} // for controller call 1
{"y":{"id":"2", "x":{"id":"1"}}} // for controller call 2
So those are the options I am juggling with at the moment, and I wouldn't mind getting some feedback and some pointers on how others have done it.
You should use Jackson to manage your json marshalling. Then you can add annotations to your model object which tell Jackson how to handle this type of relationship. http://wiki.fasterxml.com/JacksonFeatureBiDirReferences is a good reference for how to set up these relationships.

How to get Castle MonoRail's DataBinder/SmartDispatcherController to bind against types containing properties that are interfaces?

We're using interfaces to represent entity classes in our domain model. We have concrete implementations of these by virtue of using LinqToSql. We have added a factory method to each LinqToSql class which our service layer uses to instantiate a new entity (note; as opposed to the controller's DataBind attribute doing it).
MonoRail's default DataBinder implementation will ignore properties that are defined as interfaces.
Ideally, we don't want to instantiate our data-layer classes in MonoRail - the whole point of the interfaces is to separate these concerns.
Also, we don't really want to create another set of non-LinqToSql concrete classes whose only job is to translate between layers.
It's the end of a really long day over here; please can someone have mercy and point us at the parts of IDataBinder that we should overload with our own implementations, or hint at other approaches we might attempt? ;-)
You should be looking at IParameterBinder. take a look at a post I've written on the subject
As Ken pointed, your idea could be implemented with a custom IParameterBinder.
A solution would be to use IOC:
resolve concrete instance of the form from it's interface
then use IDataBinder to bind the instance to the request params
Another one would be using IDictionaryAdapter:
generate a dto proxy for your interface
then use IDataBinder to bind the dto proxy instance to the request params
NB: second option won't work if interface:
is not public (hum)
has methods
or events
or readonly properties
or setonly properties
Last, I'm unsure of what is the problem exposing concrete class in controller's signature.
I myself use concrete form in controllers implementing interface defined in application layer services, it allows me to have concerns separated on both side:
controller side is Http mapping and first level data validation of the form/command
application layer services is business validation and processing of the form/command