Spring MVC - how to pass data from filter to controller - spring

I use Spring MVC in my web application. For every request I'd like to prepare the environment, for example load some data from the datastore and save it so every controller could access that information. I assume that's what filters are for (among other things). I can attach an information to the request variable in a filter, but how do I access it from the controller? Or is there a generally better way to do this?

I think your problem at the moment is how to get the data set in request inside your filter( already done by you) and then accessing it inside the hamdlerMapping method of your controller( you want to achieve).
I agree with both the previous answers but if you have decided to do it this way only then I think you should follow my answer.
In the handler method you have mapped your request to in your controller you can have a parameter in method signature for HttpServletRequest request and it will contain the request parameter you have set in your filter. And you can get that from this request object in your controller.
Hope this helps you. Cheers.

I don't see why this is a good thing to do, filter or no.
If you truly have read-only data that every controller needs, I think a caching solution that is loaded on startup is a better idea. I wouldn't do that with a filter, and I wouldn't burden every single request with such a thing. Once it's done, why keep repeating the action?

#duffymo is right, but if you really want to do that I suggest you to use interceptor
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor

Related

REST: Sending additional user data with some requests

I have a REST service implemented using Spring. For some requests i'd like to transfer some additional data from client, like timestamp and username (and maybe something else) to keep some kind of actions log. What is the best and correct way to achieve that?
Obviously i could pass this data as a request params or within message body, but it would probably be wrong and will force me to update appropriate controllers - is there any better way?
I am not sure if you do not want to change your controller's method signatures or not, but if you simply add HttpServletRequest into the parameters of your controller, spring will automatically inject this object. It comes with all the metadata you are looking for including date/timestamp, username, etc.
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html

Problems with Spring Forms and Validation

I am newer to Spring, previously I've worked in PHP and Python. I am having some issues understanding how Spring forms work and are validated. My understanding thus far is that when you are using the your form is backed by a bean, meaning you must provide a bean to the JSP. You can also use the stand HTML forms but then you have to manually retrieve the request parameters in the controller.
Here is the issue I am having. I have a User bean that is using Hibernate Validator, and I have add, edit pages for users. The issue is I don't want the password field to appear on the Edit page, the password is going to be garbage anyway because its using BCrypt. However when the form is submitted validation fails because it expects the password to be present. There doesn't seem to be anyway to do partial bean implementation using Spring Form.
I would like to use Spring Form if possible because it reduces repetitive validation code, and its always nice to work with objects. My thoughts now are do I create an intermediate object and then translate the data from that to my bean. Seems tedious and can lead to the creation of way to many objects. My other thought is to just using plain old HTML forms and pull the params myself and set the values in the object.
I'm not sure what is the best approach or if I'm even thinking on the right track. Spring Forms and the validation is offers seems great, but seems like it isn't particularly flexible. Like I said I'm new to Spring so I may just be missing something or not understanding.
Another issue I have been wrestling with is having multiple objects needed on a form. Lets say I have a User bean, which has the following Properties.
private Role role;
private Country country;
So I need to pass User, List, and List to my JSP. I can get them to display fine, however if the form validation fails when it returns to that page, I lose my role and country objects, unless I re-add them to the model before returning the view name. Am I missing something here or is that the norm. It's a request object so I guess that makes sense but seems tedious to have to re-add them every time.
My understanding thus far is that when you are using the your form is
backed by a bean, meaning you must provide a bean to the JSP.
I'd say mostly true. The form is backed by a bean, but the Spring JSTL tags know how to get to the bean based on the set modelAttribute. The bean is living in what you would consider "page" scope, unless you add set your model attribute to be in session. Either way, if you are using the Spring JSTL tags, they are going to one or the other place to get it.
You can also use the stand HTML forms but then you have to manually
retrieve the request parameters in the controller.
Not true. You can "simulate" the same thing that the Spring JSTL tags are doing. Understand that JSTL tags are very much like macros. They are simply copying in some pre-determined block of code into the output with some very rudimentary conditional statements. The key bit that Spring MVC needs to wire the Model Attribute on the Controller side is the name and value, which are easy to decipher how those get generated/wired together.
However when the form is submitted validation fails because it expects
the password to be present.
You could create a "DTO" or "Data Transmission Object", which is basically a go-between to take the values from the UI and are converted in the Controller/Service layer to the real Model objects on the backend. Or, if you are lazy like me, put the User in session scope, in which case you don't have to post the value as Spring will take the one out of session and just updated the one or two fields you did post. Don't post the password, Spring wont set the password.
My thoughts now are do I create an intermediate object and then
translate the data from that to my bean.
Yes, this is the DTO I referred to. You only need to do it where you need to.
I'm not sure what is the best approach or if I'm even thinking on the
right track.
There are probably thousands of ways to do anything in coding, some more right or wrong than others. I know some developers who are design-Nazi's and would say you should always do it one way or another, but I am not one of those people. I think as long as you are consistent, and you are not doing something completely boneheaded you are on the right track. My #1 concern with all the code I write is maintainability. I
Don't want to spend 20hrs trying to re-learn what I did 6mo ago, so I tend to choose the simpler option
Hate repeating code, so I tend to choose more module designs
Hate having to spend 20hrs trying to re-learn what I did 6mo ago, so tend to make heavy use of JavaDoc and comments where I find the code is tricky (lots of loops, doing something weird, etc)
Another issue I have been wrestling with is having multiple objects
needed on a form.
There are several ways to deal with this too. I have never used it, but you CAN actually have more than one Model Attribute associated with the same form and Controller handler. I think you use a <spring:bind> tag or something. I have seen samples around, so Google it if you think you need that.
My approach is usually to either put something in session or build a DTO to hold all the things I need. The first I use more for things like lists to drive building the view, for instance if I have a drop down of States coming from a table. I would have a List of the States put into session and just use them from there, that way I only go after them once and done.
I use the DTO approach (some might call it a Form Bean) when I have a complex gaggle of things I need to change all at once, but the things are not necessarily connected directly. Just to point out: You can have nested objects in your model attributes and use them in your Spring JSTL tags. You can also have Collections (List, Set, Map) in your Model Attribute and get to those as well, although Spring doesn't handle nested Collections very well.
Hope that helps.

I don't understand [Bind(Exclude="ID")] in MVC

I'm really confused by this... still.
I asked a similar question to this a while before, but i'll ask it even simpler now.
I see this in a lot of samples and tutorials. How could you put [Bind(Exclude="ID")] on an entire Model, and expect to do Edits on the model? If you get pack all the properties of a model on a POST but not the ID, then how do you know which ID to edit?
Even if i'm using ViewModels... i'm probably creating them without IDs. So in that case... also... how do I know which ID was updated on an Edit?
Yes, i understand that there is a "security" element to this. People can hijack the ID... so we need to keep people from updating the value during a POST. But... what is the correct way to handle edits then? What's common practice?
I feel like i'm missing something VERY trivial.
In MVC requests are processed by the model binder when the client makes a request. If you include models on your controllers then, as far as I'm aware, you actually have to specify the model you wish to bind to by prefixing your arguments with the model name (unless you only have one argument which is the model)
SomeModel_ID
Now, in some cases you might want to exclude certain properties from being bound to because they pose a security risk, which you seem to be happy with as a concept. We will exclude ID on the model, preventing any client request from posting this value in plain text.
Now why might we exclude an entire model? Well not all controller arguments are pre-processed by a model binder. RedirectToAction for example does not pass through the model binder, so it is conceivable in this instance for you to create a new model in a POST controller action, and redirect to a GET controller action, passing along a sanitised model. That model cannot be populated by the client, but we are free to populate it ourselves on the server side.
The only time I bind to a model is when I have a view model and an associated editor for that model. This makes it really easy to inject a common editor into a page and to encapsulate those properties. If you have to exclude certain properties from being bound to I would argue that you are doing it wrong.
Update
Following your comments I think I can see why you might be confused. The model bind excluder prevents the client from ever setting a model property. If you need this property to do your updating then you simply can't exclude it. What this does mean then is that the user could potentially post back any ID. In this case you should check that the user has permission to be modifying any objects or database records associated with this ID before serving the requested update. Validating the arguments is a manual process. You can use data annotations for validating inputs, but this isn't likely to help very much with access permissions. It's something you should be checking for manually at some stage.
You know the ID because it's passed to you through the page address. So:
http://yoursite.com/admin/users/edit/20
Will populate your ID parameter with 20. If it's used in a POST (ie, the information is filled in), just manually fill in the ID field and pass it to the database controller in whatever manner you have devised.
This is also immune to (trivial) hijacks because if they were to write some other ID besides 20, they wouldn't be updating the user with ID 20 now would they? :)

Creating logs from controllers in CakePhp

What is the best way to create logs & history in CakePHP. I was thinking if there is a way to create a Helper "that accesses" one table and then I call this helper inside of each controller that I want. However, I have read that this is not MVC standard. How would it be the correct way to do that?
I appreciate your time spent answering me that. Thanks!
thats what behaviors are for.
I use the LoggableBehavior from here:
https://github.com/alkemann/CakePHP-Assets/blob/master/models/behaviors/logable.php
works like a charm. they are then fetched and displayed in the view, if you want to.
Just implement a different log engine for that purpose. The CakeLog class actually works somewhat like an observer and the log engines like listeners.
Simply use CakeLog::write() and your custom engine that could load your log model in the constructor using ClassRegistry::init() and pass the incoming data from write() to the model.
The manual will help you with that. http://book.cakephp.org/2.0/en/core-libraries/logging.html#creating-and-configuring-log-streams

Data based entitlements/authorization in ASP.Net MVC 3

My google skills are failing me on this. I'm looking for the "right way" to do data based entitlements in ASP.Net MVC (3).
With regular entitlements where one just need to know the user and the route can be done with the [Authorize] attribute, but this doesn't appear to work with data based entitlements b/c of the need to have a connection to the data store.
Is the obvious approach of inserting a check into the action methods the right way?
Is the obvious approach of inserting a
check into the action methods the
right way?
That's what I do.
if (!userHasAuthorization)
return view("Unauthorized");
It's by far the simplest way.
To make sure you only have to do "userHasAuthorization" once, you can put a method in your repository or service layer that checks for authorization, and use that in place of the boolean value userHasAuthorization.
Without knowing what "data based entitlements" are. I do believe that custom action filters will get you what you want. This lets you manage whatever you need around authorization with having the context of the route, user, etc. Gives more fine grained control. Also gives you the re usability so you dont need to plug if statements into your action methods.
http://msdn.microsoft.com/en-us/library/dd381609.aspx
You could create a custom action filter derived from the [Authorize] attribute that uses the data store to check authorization.

Resources