user886596
user886596

Reputation: 2440

How do I check if a view exists?

I would like to check if a view exists before I actually resolve it. Here is my controller, with some comments on how I'd like it to work.

@RequestMapping(value="/somethinghere/")
    public String getSomething(Model inModel,
            @RequestParam(value="one", defaultValue=Constant.EMPTY_STRING) String one,
            @RequestParam(value="two", defaultValue = Constant.EMPTY_STRING) String two) {
        String view = one + two;
         if (a view with name equal to one + two exists) {
            return view;
        } else {
            return "defaultview";
        }                
}

I want to return a view, but only when I've verified that there is indeed a view with that name defined. How do I do this?

Upvotes: 1

Views: 2935

Answers (2)

mackie1908
mackie1908

Reputation: 475

I know this is old but thought this might be of help to someone. I had a scenario where a CMS was providing the direction as to what view to render for a given content type. In this scenario it was crucial to have something in place for just this circumstance. Below is what I used to handle it.

First I injected the following into my controller

@Autowired
private InternalResourceViewResolver viewResolver;

@Autowired
private ServletContext servletContext;

Next I added this simple method to check for the existence of a view

private boolean existsView(String path) {
    try {
        JstlView view = (JstlView) viewResolver.resolveViewName(path, null);
        RequestDispatcher rd = null;
        URL resource = servletContext.getResource(view.getUrl());
        return resource != null;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

I used this like so:

    if(!existsView("components/" + fragment.getTemplate().getId())) {
        logger.warn("View for component " + fragment.getTemplate().getId() + " Not found. Rendering fallback.");
        return new ModelAndView("components/notfoundfallback");
    }

My notfoundfallback.jsp looked like this:

<div class="contact-form">
    <div class="contact-form__container container">
        <div class="contact-form__content" style="background-color: aliceblue;">
            <div class="contact-form__header">
                <h2>No design for content available</h2>
                <span>
                    You are seeing this placeholder component because the content you wish to see
                    doesn't yet have a design for display purposes. This will be rectified as soon as possible.
                </span>
            </div>
        </div>
    </div>
</div>

I hope this helps someone in the future. It worked in both standard Spring MVC and SpringBoot MVC.

Thanks,

Upvotes: 0

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279990

First, consider how view resolution is done in Spring. Assuming you are using a InternalResourceViewResolver, by default or explicit declaration, an InternalResourceView object created and the path to the resource is resolved by concatenating InternalResourceViewResolver's prefix, view name (returned by your hanbdler), and suffix.

That View object is returned. Note that with InternalResourceViewResolver that object cannot be null and therefore ViewResolver chaining cannot be achieved. The DispatcherServlet then uses the returned View object's render() method to create the HTTP response. In this case it will use a RequestDispatcher and forward to it the resource described by the View's name. If that resource doesn't exist, the Servlet container will produce a 404 response.

Given all that, unless your View is something completely different than a jsp or related resource, there's no way to check if the resource exists until the container actually forwards the request with a RequestDispatcher.

You will have to rethink your design.

Upvotes: 1

Related Questions