Reputation: 2440
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
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
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