JWSSystemServletpublic class JWSSystemServlet extends HttpServlet Servlet that responds to all Java Web Start requests for app client-related
content.
This servlet uses the path info from the incoming request and tries to locate
a Content object in the shared Java Web Start information data structure,
using the path info as a key. If such content exists and is dynamic, then
the servlet substitutes some request-based properties (such as host and port)
in the content and writes the result as the response.
If the content exists
and is static, the servlet wraps the request setting the wrapped request's
path from the relative path stored with the Content object.
directory tree. It then invokes the default servlet's method to process
the request. This is made easy because this class extends the default servlet
class.
If the path info from the request does not map to any content, then the
servlet rejects the request as not-found. |
Fields Summary |
---|
private static final String | ARG_QUERY_PARAM_NAME | private static final String | PROP_QUERY_PARAM_NAME | private static final String | VMARG_QUERY_PARAM_NAME | private static final String | LAST_MODIFIED_HEADER_NAME | private static final String | DATE_HEADER_NAME | private static final String | GET_METHOD_NAME | private final String | lineSep | private AppclientJWSSupportInfo | jwsInfo | private Logger | _logger | RequestDispatcher | defaultDispatcher |
Constructors Summary |
---|
public JWSSystemServlet()Creates a new instance of JWSSystemServlet
|
Methods Summary |
---|
public void | init()Initializes the servlet.
super.init();
String dispatcherName = getInitParameter("defaultDispatcherName");
if (dispatcherName==null)
dispatcherName = "default";
defaultDispatcher = getServletConfig().getServletContext().getNamedDispatcher(dispatcherName);
try {
/*
*Locate - or create - the data structure object.
*/
jwsInfo = AppclientJWSSupportInfo.getInstance();
} catch (Throwable thr) {
throw new ServletException(thr);
}
| private java.util.Properties | prepareRequestPlaceholders(javax.servlet.http.HttpServletRequest request, DynamicContent content)Initializes a Properties object with the token names and values for
substitution in the dynamic content template.
Properties answer = new Properties();
answer.setProperty("request.scheme", request.getScheme());
answer.setProperty("request.host", request.getServerName());
answer.setProperty("request.port", Integer.toString(request.getServerPort()));
/*
*Treat query parameters with the name "arg" as command line arguments to the
*app client.
*/
String queryString = request.getQueryString();
StringBuilder queryStringPropValue = new StringBuilder();
if (queryString != null && queryString.length() > 0) {
queryStringPropValue.append("?").append(queryString);
}
answer.setProperty("request.web.app.context.root", NamingConventions.SYSTEM_WEBAPP_URL);
answer.setProperty("request.path", request.getPathInfo());
answer.setProperty("request.query.string", queryStringPropValue.toString());
answer.setProperty("security.setting", content.getJNLPSecuritySetting());
/*
*If the content origin is a user content origin, then find out if
*the app client jar file recorded with this origin is signed or not.
*Then use that to set the property for substitution in the dynamic JNLP.
*/
ContentOrigin origin = content.getOrigin();
answer.setProperty("appclient.user.code.is.signed", Boolean.toString(content.requiresElevatedPermissions()));
processQueryParameters(queryString, answer);
return answer;
| private void | processDynamicContent(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp, Content content)Handles requests for dynamic content.
try {
DynamicContent dc = (DynamicContent) content;
/*
*Build the Properties object with the request-based tokens and values, then
*see if the DynamicContent that has already been retrieved already
*has an instance with matching content. During that search, if this
*is a GET request then add the text to the DynamicContent's cache
*if it is not already there. This helps Java Web Start manage its
*cache on the client side and avoid retrieving documents over the
*network that its cache already contains.
*/
Properties requestPlaceholders = prepareRequestPlaceholders(req, dc);
boolean isGetMethod = req.getMethod().equals(GET_METHOD_NAME);
DynamicContent.Instance instance = dc.findInstance(requestPlaceholders, isGetMethod /* if method == GET, then create if no instance */);
/*
*The findInstance invocation will return a null only if the request is an HTTP HEAD request
*(to check the timestamp) and the substituted content does not
*already appear in the DynamicContent's cache.
*/
if (instance != null) {
String responseText = instance.getText();
Date instanceTimestamp = instance.getTimestamp();
resp.setDateHeader(LAST_MODIFIED_HEADER_NAME, instanceTimestamp.getTime());
resp.setDateHeader(DATE_HEADER_NAME, System.currentTimeMillis());
resp.setContentType(dc.getMimeType());
resp.setStatus(resp.SC_OK);
/*
*Only for GET should the response actually contain the content.
*/
if (isGetMethod) {
PrintWriter pw = resp.getWriter();
pw.println(responseText);
pw.flush();
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("JWSSystemServlet: serving dynamic content: method=" + req.getMethod() +
", pathInfo=" + req.getPathInfo() +
", queryString=" + req.getQueryString() +
", isGetMethod=" + isGetMethod +
", content timestamp=" + instanceTimestamp +
", content=" + responseText
);
}
} else {
/*
*The Java Web Start client has sent a HEAD request for
*a URL that we recognize as one we should serve, but we have no
*such document (yet). Report the requested
*document as here with the current date/time. That will cause
*Java Web Start on the client to re-request the full document
*using a GET.
*/
resp.setDateHeader(LAST_MODIFIED_HEADER_NAME, System.currentTimeMillis());
resp.setDateHeader(DATE_HEADER_NAME, System.currentTimeMillis());
resp.setContentType(dc.getMimeType());
resp.setStatus(resp.SC_OK);
}
} catch (Throwable thr) {
throw new ServletException("Error processing dynamic content for path " + content.getPath(), thr);
}
| private void | processQueryParameters(java.lang.String queryString, java.util.Properties answer)
if (queryString == null) {
queryString = "";
}
String [] queryParams = null;
try {
queryParams = URLDecoder.decode(queryString, "UTF-8").split("&");
} catch (UnsupportedEncodingException uee) {
throw new ServletException("Error decoding query string", uee);
}
QueryParams arguments = new ArgQueryParams();
QueryParams properties = new PropQueryParams();
QueryParams vmArguments = new VMArgQueryParams();
QueryParams [] paramTypes = new QueryParams[] {arguments, properties, vmArguments};
for (String param : queryParams) {
for (QueryParams qpType : paramTypes) {
if (qpType.processParameter(param)) {
break;
}
}
}
answer.setProperty("request.arguments", arguments.toString());
answer.setProperty("request.properties", properties.toString());
answer.setProperty("request.vmargs", vmArguments.toString());
| private void | processStaticContent(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp, Content content)Handles requests for static content by delegating the request to
the default servlet.
try {
StaticContent sc = (StaticContent) content;
/*
*Set up the wrapped request with a URI to the file to be served that
*is relative to the app server's installation root directory. The
*web container has initialized this web app's docbase to the app
*server's installation root.
*/
HttpServletRequest wrappedRequest = new JWSSystemServletRequestWrapper(req, sc.getRelativeURI());
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("JWSSystemServlet: serving static content: method=" + wrappedRequest.getMethod() + ", mapped path=" + wrappedRequest.getPathInfo());
}
/*
* Send to the dispatcher for the default servlet.
*/
defaultDispatcher.forward(wrappedRequest, resp);
} catch (Throwable thr) {
throw new ServletException("Error processing static content for path " + content.getPath(), thr);
}
| public void | service(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response)Delegates the request to either this servlet's specialized handling for
dynamic content or to the default servlet's handling for static content.
if ( ! (request instanceof HttpServletRequest) || ! (response instanceof HttpServletResponse)) {
throw new ServletException("Expected HttpServletRequest and HttpServletResponse but received " + request.getClass().getName() + " and " + response.getClass().getName());
}
boolean isFine = _logger.isLoggable(Level.FINE);
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
/*
*See if there is Content info
*available for this request.
*/
Content content = jwsInfo.getContent(req);
if (content == null) {
try {
if (isFine) {
_logger.fine("JWSSystemServlet: content not found for request: method=" + req.getMethod() + ", pathInfo=" + req.getPathInfo());
}
resp.sendError(resp.SC_NOT_FOUND, req.getPathInfo());
} catch (Throwable thr) {
throw new ServletException("Error attempting to return not-found response", thr);
}
} else {
/*
*If the response is static, delegate to the default servlet logic.
*Otherwise, handle it here.
*/
if (content instanceof StaticContent) {
processStaticContent(req, resp, content);
} else {
processDynamicContent(req, resp, content);
}
}
|
|