Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.tectonica.util;
  
  import java.io.Reader;
  import java.io.Writer;
 
 
 
 public abstract class StaticServlet extends HttpServlet
 {
 	private static final long serialVersionUID = 1L;
 
 	public static interface BasicAuthorizer
 	{
 		public boolean isAuthorized(String usernameString password);
 	}

Returns the exact path, within the WAR file, of the resource to return (given an requested HTTP url, passed in two parameters for this function). The path is relative to the 'webapp' folder.

If your goal is to serve resources without changing your tree structure (which will later allow you to activate/deactivate this servlet without having to change any URLs), first make sure to have a mapping like this in web.xml (assuming, of course, that the resources are under /webapp/apidocs):

 <servlet-mapping>
     <url-pattern>/apidocs/*</url-pattern>
 </servlet-mapping>
 
then, when overriding this function, simply return:
 return servletPath + uriPath;
 
This is probably the most typical scenario, certainly when the use-case is restricting access to the static content, but not the only one possible.

Parameters:
servletPath the mapped part of the resource URL, as indicated in the <servlet-mapping> paragraph
uriPath the remaining part of the resource URL, typically ending with a file extension
 
 	protected abstract String getLocalPath(String servletPathString uriPath);

Returns an (optionally null) search-replace resolver to apply on textual content before serving them. This resolver may be created like that:
 Map<String, String> tokens = new HashMap<String, String>();
 
 tokens.put("name", "zach");
 tokens.put("email", "zach@tectonica.co.il");
 
 return new MapTokenResolver(tokens);
 
When such resolver is applied, any occurrence of $name and $email will be replaced with the corresponding values listed above.
 
 	protected TokenResolver getTokenResolver(String localPath)
 	{
 		return null;
 	}

Returns an (optionally null) authorizer to use before serving resources. If you wish to apply a more sophisticated authorization scheme, you need to override checkAuthorization(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse).
 
 	{
 		return null;
 	}

Performs authorization check before serving a resource. The default behavior is to apply an HTTP BASIC AUTHORIZATION strategy using a user-supplied implementation of StaticServlet.BasicAuthorizer. If the user doesn't supply such implementation in getBasicAuthorizer(), the resource is assumed cleared to serve.

an example for using Google App Engine's Accounts API is as follows:

 @Override
 protected boolean checkAuthorization(HttpServletRequest request, HttpServletResponse response) throws IOException
 {
     boolean authorized = false;
 
     UserService userService = UserServiceFactory.getUserService();
     if (userService.isUserLoggedIn())
         authorized = ApiProxy.getCurrentEnvironment().getEmail().endsWith("@tectonica.co.il");
 
     if (!authorized)
         response.sendRedirect(userService.createLoginURL(request.getRequestURI()));
 
     return authorized;
 }
 

Returns:
whether or not the resource is authorized for serving. if false, the main doGet() execution stops.
	protected boolean checkAuthorization(HttpServletRequest requestHttpServletResponse responsethrows IOException
	{
		BasicAuthorizer basicAuthorizer = getBasicAuthorizer();
		if (basicAuthorizer == null)
			return true;
		String authHeader = request.getHeader("Authorization");
		if (authHeader != null && authHeader.startsWith("Basic "))
		{
			String[] values = new String(DatatypeConverter.parseBase64Binary(authHeader.substring("Basic ".length()))).split(":");
			return (values != null) && (values.length > 1) && (basicAuthorizer.isAuthorized(values[0], values[1]));
		}
		response.setHeader("WWW-Authenticate", String.format("Basic realm=\"%s\""request.getHeader("Host")));
		return false;
	}

Override if you wish to modify the response headers before the resource is served. This could be a good place to add client-side caching for the resource, like that:
 response.setHeader("Cache-Control", "max-age=900,must-revalidate"); // 15-minutes
 
	protected void setCustomHeaders(HttpServletResponse response)
	{}
	protected void doGet(HttpServletRequest requestHttpServletResponse responsethrows ServletExceptionIOException
	{
		String uriPath = request.getPathInfo();
		String servletPath = request.getServletPath();
		String localPath = getLocalPath(servletPathuriPath);
		if (is == null)
		{
			return;
		}
		if (!checkAuthorization(requestresponse))
			return;
		String mimeType = getMimeType(responseuriPath);
		response.setContentType(mimeType);
		if (!returnManipulatedText(isoslocalPathmimeType))
			writeBinary(isos); // i.e. return as-is
		os.close();
	}
	protected String getMimeType(HttpServletResponse responseString path)
	{
		String mimeType = getServletContext().getMimeType(path);
		if (mimeType == null)
			mimeType = "application/octet-stream";
		return mimeType;
	}
	private boolean returnManipulatedText(InputStream isOutputStream osString localPathString mimeTypethrows IOException
	{
		TokenResolver tokenResolver = getTokenResolver(localPath);
		if ((tokenResolver != null) && mimeType.startsWith("text/"))
		{
			SearchReplaceReader reader = new SearchReplaceReader(new InputStreamReader(is), tokenResolver);
			writeText(readerwriter);
			return true;
		}
		return false;
	}
	protected void writeBinary(InputStream inOutputStream outthrows IOException
	{
		int read;
		final byte[] data = new byte[8192];
		while ((read = in.read(data)) != -1)
			out.write(data, 0, read);
	}
	protected void writeText(Reader inWriter outthrows IOException
	{
		int read;
		final char[] data = new char[8192];
		while ((read = in.read(data)) != -1)
			out.write(data, 0, read);
	}
New to GrepCode? Check out our FAQ X