I am looking into a solution that would allow to load an external URL content into an <iframe>
element in a JSP page.
However, before displaying any content, JSP code would first check for HTTP response of included in iframe's src URL and if 200/OK returned then display it otherwise a custom message or another page is displayed instead. I'd like to do it on the server side only.
Is there a way of achieving it without AJAX / user side scripting that could have potential cro开发者_如何学JAVAss-browser incompatibilities?
You can make use of JSTL (just drop jstl-1.2.jar in /WEB-INF/lib
) c:import
tag to import an external resource, which will throw FileNotFoundException
if the URL is invalid, which in turn can be catched using JSTL c:catch
tag. You can finally use JSTL c:choose
to check whether to display the iframe or the eventual error.
Here's an SSCCE, copy'n'paste'n'run it (with JSTL installed):
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!doctype html>
<html lang="en">
<head>
<title>SO question 2291085</title>
</head>
<body>
<c:set var="url" value="http://google.com" />
<c:catch var="e">
<c:import url="${url}" varReader="ignore" />
</c:catch>
<c:choose>
<c:when test="${empty e}">
<iframe src="${url}"></iframe>
</c:when>
<c:otherwise>
<p>Error! ${e}</p>
</c:otherwise>
</c:choose>
</body>
</html>
Change http://google.com
to http://google.com/foo
or something invalid, you'll see that the error shows instead.
Note that I used varReader="ignore"
to have it buffered but unread, so that it won't entirely hauled in which may be expensive because after all you're requesting the same URL twice.
Update: Alternatively, you can use a Servlet
for this which preprocesses the request inside doGet()
method with help of java.net.URLConnection
. Here's a kickoff example.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
URL url = new URL("http://google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
int status = connection.getResponseCode(); // 200 = OK, 404 = Not Found, etc.
if (status == 200) {
request.setAttribute("url", url);
} else {
// Do your thing to set custom message or request another page.
}
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
}
...and in page.jsp
then just have something like
<c:if test="${not empty url}">
<iframe src="${url}"></iframe>
</c:if>
Map the servlet on an url-pattern
of something like /foo
and call it on http:/example.com/contexty/foo
instead of the JSP.
The actual loading of the <iframe>
is going to take place because the client loads it. There have simply got to be better ways of validating the URL than by trying to include it via JSP. Do it in Java, or just don't do it at all: have the server return a "not found" page that runs some Javascript to hide the iframe. (Have it show an error for people browsing with Javascript turned off.)
精彩评论