Created
January 20, 2012 23:33
-
-
Save ryan-beckett/1650221 to your computer and use it in GitHub Desktop.
A servlet to display the (public) files in your web root.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.service.file; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.PrintWriter; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.servlet.ServletException; | |
import javax.servlet.annotation.WebServlet; | |
import javax.servlet.http.HttpServlet; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
/** | |
* Displays the files in your web root. Includes flags to hide internal files | |
* (INF folders, JSP pages, etc). This is a less-secure alternative for file | |
* downloads. Requires SDK 6 and Java EE 6. If your using a previous version, | |
* revert back to using web.xml for your mappings. | |
* | |
* @author Ryan Beckett | |
*/ | |
@WebServlet("/DirectoryServlet") | |
public final class DirectoryServlet extends HttpServlet { | |
private static final long serialVersionUID = 1L; | |
private PrintWriter out; | |
private final Logger console = Logger.getLogger("DirectorySerlvet"); | |
private static final boolean hideInternal = true; | |
private static final String[] internalFileExtensions = { "html", "xhtml", | |
"jsp", "inf" }; | |
public DirectoryServlet() { | |
super(); | |
} | |
protected void doGet(HttpServletRequest request, | |
HttpServletResponse response) throws ServletException, IOException { | |
doPost(request, response); | |
} | |
protected void doPost(HttpServletRequest request, | |
HttpServletResponse response) throws ServletException, IOException { | |
setHtmlOutputStream(response); | |
File dir = parseDirectory(request); | |
File[] files = listFiles(dir); | |
Collection<String> anchors = createFileAnchors(dir, files); | |
String dirPath = getPathRelativeToParent(getWebRootAsFile(), | |
dir); | |
renderPage(dirPath, anchors); | |
} | |
private File parseDirectory(HttpServletRequest request) { | |
String dir = request.getParameter("dir"); | |
if (dir == null) | |
return new File(getRealPathOfWebRoot()); | |
else | |
return new File(getRealPathOfWebRoot() + dir); | |
} | |
private String getRealPathOfWebRoot() { | |
return this.getServletContext().getRealPath(""); | |
} | |
private File[] listFiles(File dir) { | |
return dir.listFiles(); | |
} | |
private Collection<String> createFileAnchors(File parent, File[] files) { | |
Collection<String> anchors = new ArrayList<String>(); | |
if (files != null) { | |
for (File file : files) { | |
if (canShowFile(file)) { | |
String anchorTag = createAnchorTag(file); | |
if (anchorTag != null) | |
anchors.add(anchorTag); | |
} | |
} | |
} | |
return anchors; | |
} | |
private boolean canShowFile(File file) { | |
if (hideInternal) { | |
if (isInternal(file)) | |
return false; | |
} | |
return true; | |
} | |
private boolean isInternal(File file) { | |
String fileName = file.getName(); | |
for (String ext : internalFileExtensions) | |
if (fileName.toLowerCase().endsWith(ext)) | |
return true; | |
return false; | |
} | |
private String createAnchorTag(File file) { | |
if (file.isDirectory()) | |
return createDirectoryAnchorTag(file); | |
else | |
return createFileAnchorTag(file); | |
} | |
private String createDirectoryAnchorTag(File file) { | |
return "<a href=\"" + getWebRootName() + "/DirectoryServlet?dir=" | |
+ getPathRelativeToParent(getWebRootAsFile(), file) + "\">" | |
+ file.getName() + "</a>"; | |
} | |
private String createFileAnchorTag(File file) { | |
return "<a href=\"" | |
+ getPathRelativeToParent(getWebRootAsFile().getParentFile(), | |
file) + "\">" + file.getName() + "</a>"; | |
} | |
private void renderPage(String dir, Collection<String> anchors) { | |
printOpeningHtmlTags(); | |
if (dir.equals("")) | |
dir = getWebRootName(); | |
printHtml("<h1>Index of " + dir + "</h1><br/>"); | |
for (String link : anchors) | |
printHtml(link + "<br/>"); | |
printClosingHtmlTags(); | |
} | |
private String getPathRelativeToParent(File parent, File file) { | |
String[] tokens = file.getAbsolutePath() | |
.split(parent.getAbsolutePath()); | |
if (tokens.length < 2) | |
return "/"; | |
else | |
return tokens[1]; | |
} | |
private String getWebRootName() { | |
return this.getServletContext().getContextPath(); | |
} | |
private File getWebRootAsFile() { | |
return new File(getRealPathOfWebRoot()); | |
} | |
private void setHtmlOutputStream(HttpServletResponse response) { | |
try { | |
out = response.getWriter(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
private void printHtml(String html) { | |
out.print(html); | |
} | |
private void printErrorHtml() { | |
printHtml("There was an error.<br/>"); | |
} | |
private void printOpeningHtmlTags() { | |
out.print("<html><head><title>Directory</title></head><body><div>"); | |
} | |
private void printClosingHtmlTags() { | |
out.print("</div></body></html>"); | |
} | |
private void logToConsole(String message) { | |
console.log(Level.INFO, message); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment