Struts2 how to create multiple views for mobile and desktop
I am creating a site which will be accessible via mobile and desktop devices. So I want to create 2 views of my application. My action code and everything else in the backend (manageers, DAOs) is same. Just JSP changes for both.
开发者_运维技巧How I can do this via Struts 2?
In struts there are many way to obtain the same thing.
In this case, the one I prefer is:
You could write an interceptor that changes the return code based on the user-agent of
the client, such that there would be versions for PC and mobile of each jsp.
In your configuration you need to have all the result codes for all jsp (or you could simply define the result through the wildcard mapping).
For example: change the result code from "success" to "mobile_success". In case you want map both results in the same jsp you can map, as I said before, in this way
<result name="*success">
not sure whether there is library for automating such task for struts 2. but if there is, using such libraries might be better
anyway, here is the theory. every browser has its own "signature" written in the request header, called "User-Agent". different browser (supposedly) has different user agent. for example, my firefox user agent is as following: Mozilla/5.0 (Windows NT 6.0; rv:5.0) Gecko/20100101 Firefox/5.0 FirePHP/0.5
basically, by detecting the user agent, you can know what browser is used to access your site. the list of mobile browser user agents can be found in http://www.zytrax.com/tech/web/mobile_ids.html
if i'm not wrong, you can retrieve the user agent in server by httpServletRequest.getHeader("User-Agent"); (correct me if i'm wrong)
you can then create an interceptor which will decide whether a client is from mobile or from desktop. that interceptor can return different result for different client type. for example, if the client is desktop, you can return "successDesktop" and if the client is mobile, you can return "successMobile".
well, hopefully someone else can come up with (far) easier solution
I am currently trying to solve this very same problem. A framework would be nice, and I'm all ears if anyone has tested and approved one. That said, I can't find anything mature enough for me to be justify moving from Struts for the mobile view.
My best solution currently is to create actions for each of the parts of my full page which will be displayed on full browsers. Then to reuse those actions to display page segments on the mobile side.
I found trying to make one page look right for a desktop browser and a mobile browser simultaneously was not a sustainable approach.
jQuery mobile looks like a very promising library for styling the elements retrieved by struts.
So while it is surely possible to cram both versions of the site into one action I think taking the time to create small reusable actions that result in jsp snippits will pay off as your app scales.
Here are some possibilities for the near future:
(I can't add these as links as I don't have enough reputation...you'll have to add the 'http://www.')
Struts2 jQuery Mobile Project homepage: http://code.google.com/p/struts2-jquery/
Struts2 jQuery Mobile project: code.google.com/p/struts2-jquery/downloads/detail?name=struts2-jquery-mobile-showcase-3.1.1.war
an example of struts2 jQuery Mobile: weinfreund.de/struts2-jquery-mobile-showcase/index.action
@fajrian - using 'user agent' to determine a browser type could become a real pain as more and more mobile and desktop browsers are released. A better approach would be to determine whether to display a mobile version or full version based on the window's dimensions. A perfect example.
edit - Check out CSS3 media queries.
As Maurizio said you could use interceptors. Here is what I found.... http://www.benmccann.com/blog/struts-2-tutorial-interceptors/
This works for me and should basically get round the problem. You do need to know at least part of the user agent strings though:
public class MobileInterceptor extends AbstractInterceptor {
private static final String RESULT_CODE_SUFFIX_MOBILE = "mobile";
private static final String REQUEST_HEADER_ACCEPT = "Accept";
private static final String[] MOBILE_BROWSER_UAS = {"iPhone OS","Android","BlackBerry","Windows Phone"};
public String intercept(ActionInvocation invocation) throws Exception {
invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation, String resultCode) {
// check if a wireless version of the page exists
// by looking for a wireless action mapping in the struts.xml
Map results = invocation.getProxy().getConfig().getResults();
System.out.println("Results:"+results.toString());
if(!results.containsKey(resultCode + RESULT_CODE_SUFFIX_MOBILE)) {
return;
}
// send to mobile version if mobile browser is used
final String acceptHeader = ServletActionContext.getRequest().getHeader(REQUEST_HEADER_ACCEPT);
//Get User Agent String
String userAgent = ServletActionContext.getRequest().getHeader("User-Agent");
System.out.println("UA: "+userAgent);
//Boolean to indicate whether to show mobile version
boolean showMobileVersion = false;
//Run through each entry in the list of browsers
for(String ua : MOBILE_BROWSER_UAS){
if(userAgent.toLowerCase().matches(".*"+ua.toLowerCase()+".*")){
showMobileVersion = true;
}
}
if(showMobileVersion) {
invocation.setResultCode(resultCode + RESULT_CODE_SUFFIX_MOBILE);
}
}
});
return invocation.invoke();
}
精彩评论