Does Spring 4 keep an internal record of the mappings that are specified with #RequestParam? I am looking for a list of these mappings.
For example, if I annotate a method with:
#RequestMapping(value = "/myname", method = RequestMethod.POST)
I would want a list with myname.
I looked around a bit and I know about the Spring MVC Router project but I am simply looking for a method call that would return the mappings. Or alternatively, a list of all the paths registered with <mvc:view-controller/> would work too.
Background:
We have a business requirement to create public areas on our web application, similar to the tumblr model where you can have myname.domain.com and access an area created by that user. However, our method is using domain.com/myname since programmatically creating the former was not simple (would need to monkey with DNS/web server config files).
We extended GenericFilterBean to do this, but I want to make sure that when searching for 'myname,' the application can ignore actual pages (or more specifically, views) on the site. We want the front-end validation to disallow existing page names.
I think your question was already answered in here. This is a very good answer.
Related
so I'm pretty new to Spring and used the Spring Initializr to create a new project. I do not have any configuration .XMLs or similiar configuration files. I followed this tutorial to get things going.
My controller class basically looks like the following:
#Controller
#Configuration
#EnableScheduling
public class IndexController {
#GetMapping("/")
public String index(Model m) {
m.addAttribute("Title", "New Website");
m.addAttribute("MenuOne", InformationProvider.getMenuOneLink());
m.addAttribute("MenuTwo", InformationProvider.getMenuTwoLink());
m.addAttribute("StaffNumber", InformationProvider.getNumberOfStaff());
m.addAttribute("Birthdays", InformationProvider.getBirthdaysOfToday());
return "dashboard";
}
}
This works fine and everything is doing what it is supposed to be. Unfortunately the attributes which are getting their data by the InformationProvider class need to be updated at run time. The InformationProvider is approaching different APIs on the web and my idea either was to pull data from these APIs every 10 hours for example or to pull the data again on a site refresh.
From my understanding my method is supposed to be called each time someone would enter the URL localhost:8080/. My first idea basically was to refresh the site after 10 hours. The method is called when the site is refreshed and it is returning "dashboard" each time but the values are not updated. To update my attributes I have to restart my application. I was looking at the #scheduled annotation but this does not really help me since it is only working for methods which have void as return time and do not have object parameters. So scheduling my method index doesn't work and is probably the wrong way to go anyway.
I was googling a lot regarding this topic but I couldn't really find a solution for this specific problem where you only have a model as parameter in your controller method and want to update it afterwards.
What is the best approach for this problematic? I was checking the JavaDoc of the model class but it does not contain a remove or update method. Do I need to approach the HashMap behind the model directly and overwrite an attribute by an existing key to update it?
Edit:
To be more specific about the InformationProvider class, it is basically returning a String received by a cURL method called from Java. Nothing more.
Thanks in advance
InformationProvider class need to be updated at run time
If you tried to Schedule this exact method, its possible that due to InformationProvider class being a static class, it serves the data when it was first initialized. It's hard to tell without seeing what happens in that class. I would rather #Schedule a Service that populates this Object, or rather from a storage, where you can read the cached data.
Regarding your real problem, fetching from different sources.
#Schedule is good for running jobs, but I would avoid, unless you need to cache the data in your server. If it's possible, you can do it live, always fresh data, and easier.
In general for the problem.
I would fetch the data (cache is speed is crucial), with a service that you can Schedule, but have other controls over it for e.g. force refresh from another endpoint, do transformation on server side, and stream it to your page via the model. That should be the basic flow.
The solution for this problem was pretty simple, I just had to refresh the page for example by javascript. Might be as well be able to do this by scheduling.
With all the tutorial out there, I managed to make a view displayed by a controller. However, I don't understand how do I allow the user to navigate through the site with MVC. Every request to the server must go through the controller? If every request must go through the controller, how am I supposed to let the controller define the type of response it should forward the request to.
Edit: I'm doing a school project which required me to convert my current not reusable code to MVC pattern but I'm not understanding the navigation part of different views. How to get from one view to another view. For example, the navbar element should point to the controller or the view?
The controller comes first, it comunicate with the model and send you to the view you want.
So, for what you need, in the view, just put some link with the url mapped in the controller you want...
The short answer is that all actions "point" to the controller with a parameter telling it what the action is supposed to be, together with any other necessary parameters.
Suppose you have a simple registration form. You may have the following two actions: showRegistration and Register. MVC is not specific to the web, but I will provide the examples in that context (based on your comments). These two actions will point to your controller (say index.jsp) with URLs like this: /index.jsp?act=showRegistration and /index.jsp?act=Register.
Your controller will then have different logic for the different actions (you can do it in many ways yourself, or use some framework which does this switching logic for you). At the end of the day the logic in the controller will boil down to something like this:
if showRegistration:
model.getCountries //to populate a dropdown maybe
view.showRegistrationForm
if Register:
model.validateRegistrationForm
if not valid
view.showRegistrationNotValid
else
model.createUser
if userCreated
view.showSuccess
else
view.showCouldNotCreate
The idea is that the Controller contructs the full action using reusable model and view components. You can use the same model.getCountries in many different places, thus reusing the logic of retrieving a country list.
In practice, it requires a nontrivial effort to generalize the model and view actions. I've seen many projects decent into a chaos of hundreds of components created for a single purpose and used only once, and many components which are essentially duplicates because the developer did not know a similar one already exists, or needed slightly different logic and did not want to bother modifying the old code.
This post makes it easy to set up a custom validation tag using Play 2.1(or 2).x "How to create a custom validator in Play Framework 2.0?". My use case, however, is a little different and I am hoping for a UI Play Framework Jedi Master that can provide some sort of direction. We have the normal MVC pattern to create reports, and for most scenarios, having validation in the play model using custom tags works fine. One of our use cases, however, is for custom "dynamic" validation. If we use the "Required" case, as an example, its easy to say that when form ABC loads, then fields X, Y and Z are required - But what if you dont know the list of required fields until just before the form is rendered and the list of required fields is provided to you in a json file from a db read in the controller. How, then, would you cater for this with the Play framework?
I may have a solution but without annotation. Create a validate method on your form (see http://www.playframework.com/documentation/2.2.x/JavaForms)
You'll be able to do all the checks you want there.
For new project, I was searching for which framework is to be used. I looked for the updates for existing frameworks.
I found it very intresting about Spring MVS controller, that in the controller itself you can now define which URL you want to hit. The best thing is that you do not need to rewrite url, that kind of feature is also there, i.e., you can give directly the url like:
\users\amit\stores\store1
Earlier I had to write url rewriting for making it this way, and actual url used to be like:
\StoreDetails?user=amit&store=store1
I found it very good. But on second thought, if I compare, if I start putting the urls in controller itself, will not it make a little difficult to maintain after say 1 year, when I have so many modifications done on the project and at times, the url given to Controller turns not related to the name of the Controller.
For example in above example, I might want to search for storedetails, but by url i would be searchin in StoreController etc.
What you guys suggest is good practice, to go with xml or to go with annotation based.
If you guys using the annotation based, do you face any issue?
Thanks & Regards
Amit
Spring MVC implements a lot of predefined conventions. For example if you do not explicitly define #RequestMapping on controller it will map it to url similar to controller name. For example if you controller is named Users it will be automatically mapped to url users. If then you rename your class to Customers it will be automatically mapped to url customers.
The same happens with methods.
The big question is whether you really want this. Typically you do not want your internal changes (including class renaming) directly and automatically affect API your provide.
If you choose to define mappings explicitly try to organize your project using certain convention that will simplify on-going support in future. You can also use public static final Strings in annotations. All URL dependent strings can be stored in one class, for example:
public interface Mapping {
public final static String USERS = "users";
public final static String PERMISSIONS = "permissions";
}
#RequestMapping(Mapping.USERS)
public UserController {
............
}
I would stick with annotations they are very simple to define and its pretty easy to discover the appropriate method from a view using a good IDE. They key is to search the entire project for a given URL string.
So for example, if I had the following jsp.
Store Link
I would just use the IDE's search feature (in Eclipse > File Search) to find /store/products/ which would most likely contain the controller in my search results. If your crafty with IDE search features the annotation mappings are really a non issue.
For a web application, I need to return a model to a view.
For a mobile application or API, I want to return xml or json.
Is it possible to do all of these using a single controller method, or do I have to duplicate this and create seperate API controller's etc?
With Spring MVC 3.x you can do this with just the one controller method. The trick is to wire up the appropriate ContentNegotiatingViewResolver in your Spring config. You can configure it to return the desired content type based on file extension and/or requested mime type.
It works best for methods that only add a single model attribute to the Model, otherwise the JSON/XML starts to get a bit ugly.
I often find its simpler/nicer to implement separate controller methods for my web service requests, as you can better control the format of the JSON/XML and the code is easier to maintain in the long term.
EDIT: Just to qualify my comment above, I find that complex JSP pages where there might be up to 5-10 model attributes added to the page, that the resulting JSON tends to be quite messy and you usually find you only really want 1-2 of those in the JSON. OTOH, simple pages with 1-2 models added work quite well.