In a Spring MVC application using Sitemesh to decorate my views, I want to inject into every Model a security attribute called sec of type WebSecurityExpressionRoot.
This way I could call hasAnyRole(), hasAuthority()... in all my views so administrators would be presented extra stuff by the underlying templating engine (Thymeleaf BTW).
A custom HandlerInterceptorAdapter with an overridden postHandle(...) seems to be Spring MVC's way of accomplishing this, but it seems that my master Sitemesh decorator is kind of stealing my security attribute, because whenever I try to reference in some views it is null.
BUT only the views rendered after one of my controllers are affected, the ones
mapped with mvc:view-controller do have the sec attribute.
I'm considering writing a Filter to stash sec into the current HttpServletRequest to solve this issue but I'm maybe missing something.
Thanks in advance!
Are you sure the mvc:view-controller views/path are hitting the interceptor?
Also, I don't know about Thymeleaf, but using JSPs (eg, JstlView) makes Spring MVC copy Model into Request attributes (for purposes of rendering the view) -- the fact that Sitemesh also gets the values via request attributes is, I think, a consequence.
Related
I'm way new to Spring.
I am looking to verify the following understanding of SpringMVC lifecycle-- to put things into places in the overall view:
The entire process is request-driven.
There is a Front Controller pattern and the Front Controller in Spring MVC is DispatcherServlet.
Upon every incoming request from the user, Spring manages the
entire life cycle as described in here.
In the overall view, DispatcherServlet dispatches the request to a controller for a service at the back-end.
Once this is done, it hands it in to the View component of MVC for its view to be prepared in response to the user.
In more detail,
DispatcherServlet uses Handlers to decide "which controller" to serve that request.
The controllers are/should be "light-weighted"-- should be decoupled from
the service processes at back end as a good design practice-- they hold references to the service(s) and invoke the right one(s).
Their "mission" is to control the service process(es) for building the model and handing
it back to the dispatcher for the next step.
The View component in itself has 2 parts: first the ViewResolver picks the right type of look for View to put the model into the final format for the user.
From the developer's angle-- the DispatcherServlet is a behind-the-scenes thing.
All i do is to define, and configure it, if necessary, in web.xml.
As the developer, I instantiate an ApplicationContext (there are many ApplicationContext types-- i pick one depending on what i need, typically the
WebApplicationContext(?) ). AplicationContext is the factory that creates all the servlets/beans including
the DispatcherServlet, using their descriptions in the .xml files. The DispatcherServlet then runs behind the scenes and manages the
entire process-- goes&gets the controllers, using the annotations or the their .xml descriptions,
views, handlers, validators etc.
I am wondering whether this description is holds-- valid&complete, and whether there are big missing pieces in it.
Thanks in advance.
Let's go into detail step by step
DispatcherServlet uses Handlers to decide "which controller" to serve
that request
The DispatcherServlet maintains an ordered List of HandlerMapping beans (which it loaded from the WebApplicationContext). A HandlerMapping is
Interface to be implemented by objects that define a mapping between
requests and handler objects.
When the DispatcherServlet receives a request, it iterates over this list until it finds a matching handler object for the request in question. For simplicity, let's consider only RequestMappingHandlerMapping.
A bean of this type stores a mapping of #RequestMapping annotated methods (the actual Method object retrieved with reflection) stored as a HandlerMethod instances and wrapped in RequestMappingInfo objects that hold mapping data for matching the request, ie. URL, headers, and request parameters.
The DispatcherServlet retrieves the best matching HandlerMethod from these and any corresponding HandlerInterceptor instances which you may have registered. It retrieves these as a HandlerExecutionChain object. It will first apply any pre-handling by HandlerInterceptors. It will then try to invoke your HandlerMethod. This will typically (but not always) be a #RequestMapping annotated method inside a #Controller annotated class. This produces what Spring calls a dispatch result. The DispatcherServlet then applies post-handling by the HandlerInterceptors. It finally processes the dispatch result depending on what it is. You can see the supported return types for an idea of what that can be.
The controllers are/should be "light-weighted"-- should be decoupled
from the service processes at back end as a good design practice--
they hold references to the service(s) and invoke the right one(s).
Their "mission" is to control the service process(es) for building the
model and handing it back to the dispatcher for the next step.
In an MVC application, the controller controls operations by making changes to the model. You can do this directly in your controller or you can decouple it by implementing and providing service and business classes for that purpose. The controller depends on these, but not the other way around. Check out multilayered architectures.
The controller then builds the model (Model) which the DispatcherServlet possibly makes available to the view. I say possibly because the controller can produce a response directly without any view (think jsp) involved.
The View component in itself has 2 parts: first the ViewResolver picks
the right type of look for View to put the model into the final format
for the user.
In the typical case where the Controller handler method would return a Model, View, ModelAndView, String (and some others) object, then a ViewResolver would handle finding the correct View. The DispatcherServlet then tries to render that view by first merging the model as you said. This usually means taking all Model attributes and putting them into the HttpServletRequest attributes. The rendering step can involve rendering a jsp, generating XML, or anything at all really.
From the developer's angle-- the DispatcherServlet is a
behind-the-scenes thing. All i do is to define, and configure it, if
necessary, in web.xml. As the developer, I instantiate an
ApplicationContext (there are many ApplicationContext types-- i pick
one depending on what i need, typically the WebApplicationContext(?)
).
You don't actually need to instantiate it. The DispatcherServlet will do that itself (or use the ContextLoaderListener's) when the Servlet container calls init() on it. It will generate its own WebApplicationContext. What you can do is decide which subclass of WebApplicationContext to use. This is an important choice if you want to load your context from XML or from a Java configuration. You can do this by providing an <init-param>.
AplicationContext is the factory that creates all the servlets/beans
including the DispatcherServlet, using their descriptions in the .xml
files. The DispatcherServlet then runs behind the scenes and manages
the entire process-- goes&gets the controllers, using the annotations
or the their .xml descriptions, views, handlers, validators etc.
The ApplicationContext is also known as the Inversion of Control Container. It does not include the DispatcherServlet. The DispatcherServlet is managed by the Servlet container and not by Spring. However, it does primarily take its configuration from Spring's ApplicationContext (WebApplicationContext). It registers a number of special beans it finds in the context. You can declare these yourself or let Spring do it for you with this little bit of XML
<mvc:annotation-driven>
This will (mostly) take care of doing what you describe, ie. registering handlers, validators, views, etc.
I am wondering whether this description is holds-- valid&complete, and
whether there are big missing pieces in it.
Don't forget that a Spring MVC web application is a Servlet web application. The lifecycle of the application is therefore tied to the Servlet container.
There is no good answer to your question. "Sure" is as close as I can get.
You can configure spring using xml files or annotations or a combination of both.
You don't need to write servlets with Spring MVC, but you can if you want. Mostly you can (maybe should) create controller classes (either by extending a Spring controller class or marking a class with the #Controller annotation).
The "mission" of the controller is to perform necessary processing of requests. They do not just "control service processes"
There is no "hand it back" to the dispatcher.
The DispatchServlet must be configured in the web.xml file,
this is never optional.
You can (maybe should) have a layer between your controller classes and any web services that you will call from the controller classes.
You can have multiple applicationContexts or use a single applicationContext.
As often as not,
the View is a JSP file.
The Controller should add DTOs (data transfer objects) that are used by the view to display non-static information.
EDIT: I removed the mention of VO objects, I (like many, it seems) incorrectly conflated DTO and VO patterns.
There is no "behind the scenes".
The DispatcherServlet receives a request and passes it to the appropriate controller for processing.
Read section 17 of the Spring Framework Reference
I have a JSF2 controller/bean/view that is invoked the standard JSF way. Now I have a need to access this logic from a legacy part of the app that knows servlets and URL params only.
I thought of creating a "loader.xhtm" view that bridges the gap between non-jsf requester and the jsf part of the app. Loader will take URL params and make the necessary JSF post to backing bean. etc. One downside of this approach is - it's one extra client/server hop, a programmatic redirect. However it is simple to implement.
But is there a more clever way? I found someone who created servlet filter and explicitly created a FacesContext, started the lifecycle and the ViewRoot. Conceptually I see what is being done, but I don't know how to put it into practice. Has anyone interfaced with JSF lifecycle directly from a servlet? Do you have a sample?
Another mention of this concept.
I want to know how to use the Filter concept in Spring.
I have web application in that i have lot of jsp pages which has login.jsp is the first page. So user can only go via login.jsp no one can not to access any jsp url directly.
Filters have nothing to do with Spring. Just wire them into your web.xml if you'd like to use them.
You also have the option of implementing security - authentication and authorization - using Spring Security. I'd recommend that you look at that if you want to use Spring to solve this problem.
There's nothing special about Servlet Filters in Spring, but Spring does provide a couple of handy support classes for writing them. The DelegatingFilterProxy lets you use a normal Spring bean as a Filter instance, and OncePerRequestFilter ensures that your filter runs only once per request. (Some app servers can run the filters multiple times based on forwarding and including.)
How do Struts2 actions compare to Servlets? Can an action act as a servlet?
A Struts (Struts1/Struts classic) action was more tied to a servlet. In Struts2, things are quite different. A Struts2 action is just a POJO (plain Java class), totally decoupled from the Servlet API. This decoupling eases testing.
In the typical workflow of a Struts2 webapp, an action will be instantiated for each request and will be associated with a Servlet (it can implement the ServletAware interface if it needs to be aware of this association; normally this is not necessary nor advisable).
An important conceptual difference with Servlets (and with Struts actions) is that Struts2 actions are not reused for different requests, and hence are thread safe: say, it can happen that three http requests (simultaneous or not) are served by one servlet instance; but inthat case we will still have three different Struts2 action instances, one for each request.
Struts is an abstraction layer on top of the vanilla java servlet stuff. Actions themselves are defined by the programmer and are invoked by struts frameworks when a URL is hit (you configure what url maps to which action). So they don't really "compare" to a servlet, they are an abstraction around the functionality the servlet provides. One typical thing you do with an action is output a jsp, which is equivalent to a servlet. so what happens is
a) request comes in, gets mapped to action
b) action loads some data
c) action renders a jsp, passing loaded data to the jsp.
An action can output directly to the request/response, if that is what you want, but in most cases is probably not good practice.
Struts2 is a MVC framework implementation based on Java EE technology.
Currently I am working on small application in asp.net mvc. It is a some kind of localization tool. Our clients login on our application and they can translate terms that shows up in our applications that they use. It is happens like this:
login to localization site
find and translate certain terms for example title for button in "Catalog" application
start that application(for example, "Catalog" application from 2.) and trough web services they update local database of terms with these that are translated
It is our old solution and that works fine.
But now, I am doing refactoring of a translating tool application in asp.net mvc and I think, why we have separate logic(doubled) in mvc and in web services? Why we can't use only mvc as a web service...this way I have only one logic(fetching elements and updating) and we don't need to create wcf web service or something. And most important, I don't have mesh desktop applications with dependency on dll's in which I have this logic.
And now the question. What I can get from controller in mvc, except of views and JsonResults...can I get collections of my objects directly?
Or more plain question, how I can use asp.net mvc as a web services. What is your experience?
cheers
Marko
It really depends on your needs. You can most certainly use an ASP.NET MVC application as a data service, but it sounds like you should tease out your shared code into a common library and reference that library in both applications. There are some things that web service projects provide that would be more difficult purely as a controller action. (de/serialization, wsdl, etc...)
It really depends on what will consume your web service.
For example: jQuery consumes JsonResults well because i can return complex objects (with collections, arrays, nested objects etc) from an action and have jQuery deserialize it back to javascript object for use in the clients browser. Of course you loose type safety with the serialization process but that's pretty expected in most REST/SOAP based web services. If you really need the type safety for the consuming application, stick with WCF (or similar).
I'd just create a flag to return an action as Json. I've noticed a few sites do it this way. Say you have this action:
public ActionResult GetPeople()
{
IList<Person> result = svc.GetPeople();
return View(result);
}
..this action's result is normally rendered into some view. That's great, but if you want to use the action as a web service, you could simply change it to this:
public ActionResult GetPeople(string ajax)
{
IList<Person> result = svc.GetPeople();
if (Convert.ToBoolean(ajax))
return Json(result);
else
return View(result);
}
..so if your consuming app didnt mind the serialized Json then instead of invoking the GET request like this http://domain.com/controller/GetPeople (as a browser would to get the View), you'd just add the ajax flag like so http://domain.com/controller/GetPeople?ajax=true to return the Json. A more appropriate flag might be 'json' instead of 'ajax' - 'ajax' is common because this method is used to support downlevel browsers for actions that may optionally be invoked with ajax.
I've been thinking of adding this to my mvc app for a while but i don't like the idea of modding every action with this flag and add more if statements. My idea is to create a custom attribute to decorate actions that you want this functionality for and the attribute dynamically adds the extra flag and conditionally returns the model data as Json rather than what's originally specified. Give it a go.