I was wondering if someone has already solved this. I have a SpringMVC app and we are adding support to WebKit type mobiles (iPhone and Android basically) so I was wondering someone has found an elegant way of defining specific views depending on the client that sent the request.
I know that a simple if in a Controller implementation can do the trick, but I'm looking for something more flexible/elegant (a specific ViewResolver implementation, or an interceptor maybe).
Help will be greatly appreciated... as always =)
This is a pretty old question. What you need to do is use Spring-Mobile to achieve this in a standard elegant manner
Update: look at spring-mobile
Original answer:
It would be pretty simple to create a custom ViewResolver that resolves views based on the User-Agent header.
here is a list of mobile user agents (page removed from wikipedia). Check the header against it, and resolve a mobile view.
if the user-agent is not a mobile, then return null, thus letting other resolvers resolve a view.
make sure your resolvers are defined (in the spring xml) in the proper order, so that the mobile resolver is consulted first.
Like #Bohzo and yourself already said spring-mobile is the way to go.
As of version 1.1 you can use the LiteDeviceDelegatingViewResolver to configure the type of behavior you're describing.
Device Aware View Management
http://static.springsource.org/spring-mobile/docs/current/reference/html/device.html#device-aware-view-management
Spring Mobile includes AbstractDeviceDelegatingViewResolver, an abstract ViewResolver wrapper that delegates to another view resolver implementation, allowing for resolution of device specific view names without the need for a dedicated mapping to be defined for each view. A lightweight implementation is provided, which supports adjusting view names based on whether the calling device is normal, mobile, or tablet based.
Within your application, you can then create alternate views for normal, mobile or tablet devices, and given the proper configuration, Spring Mobile will adjust the view name to resolve to the correct one. This happens internally, without the need to add conditional logic through your controllers.
Ok I found a more specific answer. There is a problem with the solution that Bozho proposed. the fact that the ViewResolvers no longer have access to the HttpServletRequest. There is a way to access the request but its kind of dirty IMHO.
So that said, this is a very elegant and easy to implement solution. Basicly it involves a custom ViewResolver (as Bozho proposed) but it adds an handlerInterceptor that adds the User-Agent to the model so you no longer have to add it manually.
To access current Request inside ViewResolvers.
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
Related
Hi i am pretty new to Restlet, and generally building web servers. I need to support filtering like this:
http://deviceip:port/resource?id=id
So far i know how to return a json message when user invokes different resources, based on my web server state. I would attach it to router, and add class which handles that resource. But how can i return only one resource from collection based on id? What i need to change in my class which is responsible from handling of that resource. Also how can i attach this resource to router? Any help is welcome, if you can write some code snippet to help me, that would be great.
Thanks
So as i understand you can approach to this in two ways. One is explained by link above and another one is using query. So basically you font have to create another resource like in the answer from link above, instead you can just extract query with this.getQuery()
and than call method getFirstValue("id"), which will return entered id.
We are using acceptable usage policy feature to implement a requirement where the user has to accept some licence agreement before using our registered services.
We have implemented our custom AcceptableUsagePolicyRepository as proposed in the docs and the user is successfully redirected to acceptance policy view based on a condition.
At this point we need to customize this view, so we have added the generated casAcceptableUsagePolicyView.html in the overlay. Our goal is to present different terms text based on the user status(admin,typical user etc). Terms text and user status should be fetched from the database.
In a typical MVC application, a controller would be used to generate the java objects that would be finally rendered in the view.
Question: What is the recommended way of customizing the aforementioned view to dynamically render our content?
Question: What is the recommended way of customizing the aforementioned view to dynamically render our content?
The easiest way, for the time being, would be to supply your own AcceptableUsagePolicyVerifyAction bean in a #Configuration class:
#Bean
public Action acceptableUsagePolicyVerifyAction() {
return new MyAcceptableUsagePolicyVerifyAction(...);
}
In your own MyAcceptableUsagePolicyVerifyAction, you'd then fetch the user status/text you need and stuff it into the RequestContext's relevant scope. In the casAcceptableUsagePolicyView, you can next write a bit of conditional logic to determine the relevant text based on the status found in the webflow scope.
To learn about how #Configuration classes work in general, you can:
Review this post
or This post
or consult the documentation for Spring and/or Spring Boot.
I'm trying to map an url like www.host.com/{tenant-id}/home to something like www.host.com/home.xhtml?tenantId={tenant-id} where "tenant-id" is the name of the tenant that is using the app, and could be almost anything.
After some research I found many alternatives, but none of them convinces me. I'll list the alternatives so maybe I can help anyone and get some feedback on missing alternatives at the same time.
Furthermore, my app is written in java.
Pretty Faces (or Rewrite). http://www.ocpsoft.org/prettyfaces/
Htmleasy (Resteasy) https://github.com/voodoodyne/htmleasy
A filter, handmade.
URL rewrite trough proxy (Apache / HaProxy)
I tried pretty faces and get it to work. But I'm concerned about some performance issues with high load. I don't know what PF do internally, and I'm afraid that processing every request and applying filters could be bad.
A handmade filter, would be impossible to maintain.
Does anyone have experience with Htmleasy?
Do you know any other alternative?
Thanks in advance
Cristian.
Not sure if I can get a right approach for Java. I am from a .Net background. If this were given to me, i would like to create a httpmodule that intercepts each request and then translates the uri accordingly. However, it will not be required to enable the tenant code in the uri for each request, I would suggest that you initially create a tenant context from within your app and then use it for tenant identification.
This will be far more secure and easy than handling the uri changes per request.
HTH
I am developing one RCP application to capture and display http requests. The application is like a proxy tool but the functionality is very simple. Till now, I know view change could be triggered by some events: like: selection. But I don't know how to update/load/refresh the view with data changed automatically. In this case, the data should be the captured http requests.
Could you give me some insights? Thanks.
Updates
Some nice guys tell us to use observable pattern to do this. The following snippets is my code. But it does not work as expected. The ui cannot be refreshed.
IObservableList input = Properties.selfList(Sequence.class).observe(sequences); // Sequence stands for one request, sequences are a list of sequence.
tableViewer.setContentProvider(new ContentProvider());
tableViewer.setLabelProvider(new TableLabelProvider());
tableViewer.setInput(input);
Joseph
I recommend using the observer pattern. Your data becomes the subject. Every time your data is changed notify your view (observer) to refresh.
http://en.wikipedia.org/wiki/Observer_pattern
In case you parse the received data, have a look at the Eclipse Databinding framework.
The idea with this framework is that you can bind values from a model representation of the data (usually Bean or EMF) with the various SWT Controls that are used to display the data. The framework will then automatically update the content of the widgets when the model changes (and vise-versa if you let it :-)).
See this tutorial for an introduction to the framework - you can find plenty of examples and documentation on the web...
EDIT: Also see the snippets directory for various solutions to common problems...
I have a web-app in Java, Spring, Struts 2 and Hibernate, that servers multiple clients. Each client with multiple users. To create a personal feel for each client, i would like to customize the header for each client.
I'm using sitemesh as decorator, and am looking for tips or examples or someone who can point me in the right direction as to how to acomplish this in the best practice.
What would you think? Should i just code it direct in the header.jsp? Extracting the info about the logged in user and from that create a custom header by code? Or is there a more clever solution out there?
Thanks!
Update:
To further clearify what i want:
Different properties-files for each client is not an option. We are looking at potentionally hundreds of clients. It needs to be database-driven. But thats the easy part. There is no problem storing the information in db and extracting it when needed.
What im trying to figure out is if there is some sort of standard way of doing this. Some sort of filter or Action that is run before the sitemesh decorator that will provide the decorator with the correct info?
Struts2 provides application scope, for variables which are global to the application.
Load all the customer specific strings into #application scope (I would use spring to do this when the application starts up). From there referencing the strings would be pretty obvious: #application.greeting I don't like the idea of using an interceptor because there is nothing to intercept. I would say for what you are doing application scope is the perfect place. If it is a single client system I can see no reason why anything would be stored in application scope.
Aside: Tiles uses a different template paradigm than site mesh, and they have slightly different purposes. As such the two can be complimentary. Tiles relying on XML definitions can have it's definitions stored in a DB and is definitely less computationally intensive, however where there is interplay between different UI components... or disparate elements appearing on the page you need to use sitemesh. So for basic template needs tiles does everything and is quite easy to understand but say you wanted to make add a certain widget in the middle of the page which relies on JS which needs to be added to the header it would be tricky to do this in Tiles (although the obvious solution is to just roll the JS functionality into one JS file for all possible uses in a particular part of the site).
Asside 2: By using a view technology such as velocity or freemarker in conjunction with tiles it is conceivable to move the entire view layer into a database. I just thought I would mention that as for some maintenance issues that could be extremely beneficial.
Sitemesh makes it's decisions about what decoration to use based upon the requested URL string, so unless you have a reference to the client in every url - either as part of the main url string or as a known parameter, then Sitemesh out of the box is not going to help.
This leaves a few possibilities to achieve what you want;
1) Write a filter that runs before Sitemesh that adds, for example, "&clientId="xx" to every incoming request.
2) Dive into the source code for Sitemesh & look for where Sitemesh finally makes it's decision about which decorators to use and override it. I've never tried this so I don't know how practical this might be.
3) Make the style sheet definition in your jsp pages an OGNL expression and provide that information in a base action class that all your actions extend. In this way you end up with (potentially) a different CSS file for each client and you provide your customisation via CSS.
Hope that this helps.