AnchormanIrl
AnchormanIrl

Reputation: 21

Spring Mobile EnableFallback not working

I'm trying to get the fallback solution working on mobile but having some issues.

I've the following jsp structure

views
-mobile
--about.jsp
-tablet
--about.jsp
--intermediary.jsp
about.jsp
intermediary.jsp

Currently I don't have a intermediary.jsp in the mobile but I have it in the fallback directory. The resolveViewName within the AbstractDeviceDelegatingViewResolver only fires if the view is null.

    public View resolveViewName(String viewName, Locale locale) throws Exception {
    String deviceViewName = getDeviceViewName(viewName);
    View view = delegate.resolveViewName(deviceViewName, locale);
    if (enableFallback && view == null) {
        view = delegate.resolveViewName(viewName, locale);
    }
    if (logger.isDebugEnabled() && view != null) {
        logger.deb

The problem I'm having is I can't find any viewResolver to return null. The InternalResourceViewResolver doesn't return null and the UrlBasedViewResolver always returns the view name of /mobile/intermediary.jsp which doesn't exist which in turn throws a 404. Anyone know which resolver I should be using for the fallback solution to work?

Thanks,

Upvotes: 2

Views: 485

Answers (1)

Yu Jiaao
Yu Jiaao

Reputation: 4714

look at the source you will find the answer:

 public abstract class AbstractUrlBasedView{
...
         public boolean checkResource(Locale locale) throws Exception {
        return true;
    }
...
}

public class InternalResourceView extends AbstractUrlBasedView {
     //!!not override the checkResource method!!
}

 public class FreeMarkerView extends AbstractTemplateView {
 ...
 @Override
         public boolean checkResource(Locale locale) throws Exception {
            try {
                // Check that we can get the template, even if we might subsequently get it again.
                 getTemplate(getUrl(), locale);
            return true;
        }
        catch (FileNotFoundException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("No FreeMarker view found for URL: " + getUrl());
            }
            return false;
        }
        catch (ParseException ex) {
            throw new ApplicationContextException(
                    "Failed to parse FreeMarker template for URL [" +  getUrl() + "]", ex);
        }
        catch (IOException ex) {
            throw new ApplicationContextException(
                    "Could not load FreeMarker template for URL [" + getUrl() + "]", ex);
        }
    }
...
 }

so that you may be extends InternalResourceView like below:

public class MyInternalResourceView extends InternalResourceView {
    private static final boolean SEP_IS_SLASH = File.separatorChar == '/';


    protected File getTemplate(String name, Locale locale) throws IOException {
        File source;
        if(getServletContext()!=null){
            name = getServletContext().getRealPath("")+name;
            source =  new File( SEP_IS_SLASH ? name : name.replace('/',
                File.separatorChar));
        }
        else{
            source = new File( SEP_IS_SLASH ? name : name.replace('/',
                File.separatorChar));
        }
        if (!source.isFile()) {
            return null;
        }
        return source;
    }

    @Override
    public boolean checkResource(Locale locale) throws Exception {
        try {
            // Check that we can get the template, even if we might subsequently
            // get it again.
            return getTemplate(getUrl(), locale)!=null;

        } catch (IOException ex) {
             return false;
        }
    }
}

and in viewResolver set your view class

<bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:viewClass="com.xxxx.MyInternalResourceView"  p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"  p:contentType="text/html;charset=UTF-8" />

Upvotes: 0

Related Questions