Reputation: 2022
I've been writing a simple Java server over the last few weeks.
First I wanted to display the the filesystem based on where you started the server. For example, if you started the server in the src
directory, opened up a browser, and went to localhost:5555 you would see the files and directories contained in src
. Each would be linked. And I got that working fine.
If you click a directory, it shows you its contents (just like I mentioned). If you click a file, it reads the file and displays that file in plain text. If you click an image, it serves that image. This all happens in the browser and you can use the back button to return to the directory listings or file you were previously viewing. This also works fine and uses no external libraries.
This is the code I'm using to read a text file (using a reader):
private String readFile() {
BufferedReader reader;
String response = "";
try {
FileReader fileReader = new FileReader(requestedFile);
reader = new BufferedReader(fileReader);
String line;
while ((line = reader.readLine()) != null) {
response += line + "\n";
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
This is the code I'm using to serve images (an input stream instead of a reader):
public byte[] getByteArray() throws IOException {
byte[] byteArray = new byte[(int) requestedFile.length()];
InputStream inputStream;
String fileName = String.valueOf(requestedFile);
inputStream = new BufferedInputStream(new FileInputStream(fileName));
int bytesRead = 0;
while (bytesRead < byteArray.length) {
int bytesRemaining = byteArray.length - bytesRead;
int read = inputStream.read(byteArray, bytesRead, bytesRemaining);
if (read > 0) {
bytesRead += read;
}
}
inputStream.close();
FilterOutputStream binaryOutputStream = new FilterOutputStream(outputStream);
byte [] binaryHeaders = headers.getBytes();
byte [] fullBinaryResponse = new byte[binaryHeaders.length + byteArray.length];
System.arraycopy(binaryHeaders, 0, fullBinaryResponse, 0, binaryHeaders.length);
System.arraycopy(byteArray, 0, fullBinaryResponse, binaryHeaders.length, byteArray.length);
try {
binaryOutputStream.write(fullBinaryResponse);
binaryOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
What I'm attempting now is to serve PDFs. If I have a PDF in one of the directories and I click it, it should open that PDF (in whatever default reader the browser uses).
I've been Googling this topic and trying out a few things for a day or two and I can't seem to get it. I find it strange that when I click on the PDF as my code currently is, the browser seems like it's opening the PDF but no text appears. It's the standard in-browser PDF viewer that we're all used to seeing when we click a PDF link. But there's no content. It's just some blank pages.
Can anyone help with this? I'm not going to use an external library. I just want to understand how to open the PDF file in Java.
Thanks!
Upvotes: 5
Views: 6625
Reputation: 5598
Don't parse it as text, which will convert characters, possibly end lines, and might change things you don't desire. Don't buffer the whole thing as an array of bytes, but instead write directly to the output stream so there are no memory issues. Instead, just serve the file up like this:
public class FileServer extends javax.servlet.http.HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse resp)
{
OutputStream out=null;
try {
HttpSession session = req.getSession();
out = resp.getOutputStream();
resp.setContentType(-- specify content type here --);
req.setCharacterEncoding("UTF-8");
String pathInfo = req.getPathInfo();
String fullPath = -- figure out the path to the file in question --;
FileInputStream fis = new FileInputStream(fullPath);
byte[] buf = new byte[2048];
int amtRead = fis.read(buf);
while (amtRead > 0) {
out.write(buf, 0, amtRead);
amtRead = fis.read(buf);
}
fis.close();
out.flush();
}
catch (Exception e) {
try {
resp.setContentType("text/html");
if (out == null) {
out = resp.getOutputStream();
}
Writer w = new OutputStreamWriter(out);
w.write("<html><body><ul><li>Exception: ");
w.write(e.toString());
w.write("</ul></body></html>");
w.flush();
}
catch (Exception eeeee) {
//nothing we can do here...
}
}
}
}
Upvotes: 3