Reputation: 4171
I'm new to Spring MVC. I'm trying to write a controller that handles a particular route. This controller renders a View jsp and returns it.
I now want to add an error page in some particular cases (e.g., browser not supported)
How do I do that in spring?
I'm not sure if this is the right approach but here is what I've found so far: preHandle Interceptor
I can add some sort of interceptor before the controller and check if the error condition is met. Based on that I can show an error page or continue with regular flow.
Upvotes: 2
Views: 1020
Reputation: 9197
I'll suggest two possibilities.
1. Use handler interceptor. You are right. I believe this is the best option. Detect the browser type before controller and then use the browser information to show the right page.
Look at this example pseudo code, you will need the library user-agent-utils:
public class BrowserInfo {
private String name;
private int version;
public BrowserInfo(String name, int version) {
this.name = name;
this.version = version;
}
// getter, setter...
}
/**
* Detect browser type and make it available in your controller
*/
public class BrowserResolverHandlerInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//
// FROM: http://stackoverflow.com/a/13229552/1614378
//
String userAgent = request.getHeader("user-agent");
UserAgent ua = UserAgent.parseUserAgentString(userAgent);
Version browserVersion = ua.getBrowserVersion();
String browserName = ua.getBrowser().toString();
int majVersion = Integer.parseInt(browserVersion.getMajorVersion());
BrowserInfo browser = new BrowserInfo(browserName, majVersion);
request.setAttribute("browserInfo", browser);
return true;
}
}
/**
* HandlerMethodArgumentResolver. so you can use BrowserInfo as argument in you controller methods.
*/
public class BrowserInfoResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(BrowserInfo.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return (BrowserInfo) webRequest.getAttribute("browserInfo", RequestAttributes.SCOPE_REQUEST);
}
}
Now you can use it in your controller:
@Controller
@RequestMapping(value = "/")
public class RootController extends AbstractWebController {
@RequestMapping(method = RequestMethod.GET)
public String home(BrowserInfo browser, Locale locale, Model model, HttpServletRequest request) {
if("ie".equals(browser.getName()) && browser.getVersion() < 7){
return "redirect:error"; // error.jsp or browser_not_supported.jsp...
}
return "home"; // home.jsp
}
}
2. Detect the (IE) browser version in your jsp: About conditional comments
Example:
<!--[if gte IE 8]>
<style>
[styles for IE 8]
</style>
<![endif]-->
<!--[if lt IE 8]>
<style>
[styles for IE 7: hide all elements, show message label etc...]
</style>
<script>
alert("Pls update your browser. now!");
</script>
<![endif]-->
EDIT:
(3.) you can also send redirect inside interceptor. But I personally do not like that. Because you will split your "page logic" between Interceptor
and Controller
. Anyway i believe redirect by interceptor would be faster than redirect by controller.
Upvotes: 1
Reputation: 2546
Check it in a filter or a beforeInterceptor to throw an exception.
make a custom error code for your exception.
e.g Browser not supported to be - 450 and map them through web.xml like below
<error-page>
<error-code>450</error-code>
<location>/450</location>
</error-page>
now make a controller that handles this error.
take a look at this example for reference
Upvotes: 0