I am trying to display images inside my HTTP Web Server but I'm unable to. I can display the HTML. I think it is something to do with the way I handle my IO (input and output streams). There's probably a lot of mistakes in there that I haven't noticed.
import java.io.* ;
import java.net.* ;
import java.util.Properties;
public class HTTPThread extends Thread
{
private Socket socket = null;
private Properties config = null;
private String root = "";
public HTTPThread(Socket s, Properties config)
{
this.socket = s;
this.config = config;
this.root = this.config.getProperty("root");
}
public void run()
{
// InputStream in = null;
OutputStream out = null;
try
{
out = socket.getOutputStream();
PrintWriter writer = new PrintWriter(out, true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String request = reader.readLine();
writer.println("HTTP/1.1 200 OK");
writer.println("Content-Type: text/html");
writer.println();
// Search for filename
int slash = request.indexOf("/"); //find first occurrence of slash
int emptySpace = request.indexOf(" ", slash); //find first space after slash
String filename = request.substring(slash, emptySpace); //return filename
// writer.println("<b>" + filename + "</b>");
String pathname = "";
try
{
pathname = (filename == "/") ? root + filename : root;
// System.out.println(filename);
URL url = new URL(pathname);
URLConnection urlc = url.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
urlc.getInputStream()));
String line;
while ((line = in.readLine()) != null)
{
writer.println(line);
}
in.close();
}
catch (MalformedURLException e)
{
System.err.println("Don't know about host: " + pathname);
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for "
+ "the connection to: " + pathname);
System.exit(1);
}
// reader.close();
writer.close();
socket.close();
}
catch(IOException e)
{
System.out.println("Error: " + e);
}
finally
{
try
{
// in.close() ;
out.close() ;
socket.close();
}
catch(IOException e)
{
System.out.println("Error: " + e);
}
}
}
}
Are you trying to write some sort of proxy server that takes external URL from the request and returns the contents? Well, there are several issues with your code:
writer.println("HTTP/1.1 200 OK");
writer.println("Content-Type: text/html");
When browser sees the above, it assumes whatever is returned is HTML. Rendering binary image as HTML will clearly fail. Which leads us to this:
String line;
while ((line = in.readLine()) != null)
{
writer.println(line);
}
in.close();
In the loop above you are reading some external URL line-by-line (in text mode) and forwarding it to original client. This works for HTML (which is text-based) but will fail for any image (binary). You must use InputStream/OutputStream instead.
And small thing at the end:
pathname = (filename == "/") ? root + filename : root;
Do not compare strings using == operator, replace it with:
pathname = (filename.equals("/")) ? root + filename : root;
As a final note, consider using servlet container like Tomcat or Jetty, which will release you from HTTP-handling code and provide more high-level constructs.
Related
When I upload files to local system's temp directory from Mozilla Browser I get Access denied error. But if I do the same thing from Eclipse Browser I dont see any error, means it is uploading without any error:
Code:
for (Part part : request.getParts()) {
fileName = getFileName(part);
part.write(System.getProperty("java.io.tmpdir") + fileName);
}
private String getFileName(Part part) {
String contentDisp = part.getHeader("content-disposition");
System.out.println("content-disposition header= "+contentDisp);
String[] tokens = contentDisp.split(";");
for (String token : tokens) {
if (token.trim().startsWith("filename")) {
return token.substring(token.indexOf("=") + 2, token.length()-1);
}
}
return "";
Error:
java.io.IOException: java.io.FileNotFoundException: C:\Users\user\AppData\Local\Temp (Access is denied)
Allan, this is the code:
final String path = System.getProperty("java.io.tmpdir");
OutputStream out = null;
InputStream filecontent = null;
final PrintWriter writer = response.getWriter();
try {
for (Part part : request.getParts()) {
String fileName = getFileName(part);
out = new FileOutputStream(new File(path , fileName));
filecontent = part.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
File UploadedFile = new File(path + File.separator + fileName);
UploadedFile.delete();
}
} catch (FileNotFoundException fne) {
writer.println("You either did not specify a file to upload or are "
+ "trying to upload a file to a protected or nonexistent "
+ "location.");
} finally {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
if (writer != null) {
writer.close();
}
}
See this example, when create the file use two parameter as the example:
File scratchFile = new File(System.getProperty("java.io.tmpdir"), "filename.tmp");
Example:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// Create path components to save the file
final String path = System.getProperty("java.io.tmpdir");
final Part filePart = request.getPart("file");
final String fileName = getFileName(filePart);
OutputStream out = null;
InputStream filecontent = null;
final PrintWriter writer = response.getWriter();
try {
//File Temp here with two parameters
out = new FileOutputStream(new File(path , "filename.tmp"));
filecontent = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
writer.println("New file " + fileName + " created at " + path);
} catch (FileNotFoundException fne) {
writer.println("You either did not specify a file to upload or are "
+ "trying to upload a file to a protected or nonexistent "
+ "location.");
writer.println("<br/> ERROR: " + fne.getMessage());
} finally {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
if (writer != null) {
writer.close();
}
}
}
And your method:
private String getFileName(final Part part) {
final String partHeader = part.getHeader("content-disposition");
LOGGER.log(Level.INFO, "Part Header = {0}", partHeader);
for (String content : part.getHeader("content-disposition").split(";")) {
if (content.trim().startsWith("filename")) {
return content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
}
}
return null;
}
References:
Permission
Upload Method
In case of a web application, the Webcontainer might have set some SecurityManager (https://docs.oracle.com/javase/8/docs/api/java/lang/SecurityManager.html) to block write access to the local file system.
Check if this has been the case...
Same problem I was facing few minutes ago.
Your code won't work for file upload with other request parameter together.
when you're calling getParts() it takes other parameters also as parts.
Now in case of file taken as part content-dipsosition header has
form-data; name="<file-parameter-name>"; filename="<filename>"
A thing to be noted <filename> may be different if submitted from
different browser. Try to submit it from eclipse's in built browser.
Try to print and see content-disposition header by
System.out.println(part.getHeader("content-disposition"));
In case of your loop runs for other parameters taken as part, content-disposition has
form-data; name=""
Now see there is nothing like filename="", so your function to get filename returns null.
Now you calls part.write() but inside only path is passed not filename as function you called to get filename returns null. So you get exception even thought it actually uploads file.
After getting filename put a condition
if(filename.equals("")){continue;}
But that's also not a good solution as loop iterate for no reason for other parameter.
While creating a method to my class, I got an unexpected problem. I've tried solutions from other theards, but they just don't work for me. My method should simply find the line specified, copy the file skipping unnecessary line, delete the original file and rename temporary file to the name of original file. It succesfuly creates new file as expected, but then fails to delete previous one as it fails to rename temporary file to original. I can't figure out, why?
void lineDelete(String file_name, String line_to_erase){
try {
int line_number = 0;
String newline = System.getProperty("line.separator");
File temp = new File("temporary.txt");
File theFile = new File(file_name+".txt");
String path = theFile.getCanonicalPath();
File filePath = new File(path);
BufferedReader reader = new BufferedReader(new FileReader(file_name + ".txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter(temp));
String lineToRemove = line_to_erase;
String currentLine;
while((currentLine = reader.readLine()) != null) {
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)){
continue;
}
writer.write(currentLine + newline));
}
writer.close();
reader.close();
filePath.delete();
temp.renameTo(theFile);
}
catch (FileNotFoundException e){
System.out.println(e);
}
catch (IOException e){
System.out.println(e);
}
Try this code:
void lineDelete(String file_name, String line_to_erase){
try {
int line_number = 0;
String newline = System.getProperty("line.separator");
File temp = new File("temporary.txt");
File theFile = new File(file_name+".txt");
String path = theFile.getCanonicalPath();
BufferedReader reader = new BufferedReader(new FileReader(theFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(temp));
String lineToRemove = line_to_erase;
String currentLine;
while((currentLine = reader.readLine()) != null) {
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)){
continue;
}
writer.write(currentLine + newline));
}
writer.close();
reader.close();
theFile.delete();
temp.renameTo(file_name + ".txt");
}
catch (FileNotFoundException e){
System.out.println(e);
}
catch (IOException e){
System.out.println(e);
}
I could suggest a couple of reasons why the delete and/or rename might fail, but there is a better way to solve your problem than guessing1.
If you use Path and the Files.delete(Path) and Files.move(Path, Path, CopyOption...) methods, they will throw exceptions if the operations fail. The exception name and message should give you clues as to what is actually going wrong.
The javadoc is here and here.
1 - Here are a couple of guesses: 1) the file has been opened elsewhere, and it is locked as a result. 2) You don't have access to delete the file.
I'm writing a program to download a PDF file from server. I'm using some program given here Download file by passing URL using java code, this solution works fine for the sample URL provided in the first answer, but not for PDF, I'm replacing just the URL. Below is my code.
import java.io.*;
import java.net.*;
public class FileDownloadTest {
final static int size = 1024;
public static void fileUrl(String fAddress, String localFileName, String destinationDir) {
// localFileName = "Hello World";
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
try {
URL url;
byte[] buf;
int byteRead, byteWritten = 0;
url = new URL(fAddress);
outStream = new BufferedOutputStream(new FileOutputStream(destinationDir + "\\" + localFileName));
uCon = url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];
while ((byteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, byteRead);
byteWritten += byteRead;
}
System.out.println("Downloaded Successfully.");
System.out.println("File name:\"" + localFileName + "\"\nNo ofbytes :" + byteWritten);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void fileDownload(String fAddress, String destinationDir) {
int slashIndex = fAddress.lastIndexOf('/');
int periodIndex = fAddress.lastIndexOf('.');
String fileName = fAddress.substring(slashIndex + 1);
if (periodIndex >= 1 && slashIndex >= 0 && slashIndex < fAddress.length() - 1) {
fileUrl(fAddress, fileName, destinationDir);
} else {
System.err.println("path or file name.");
}
}
public static void main(String[] args) {
String fAddress = "http://singztechmusings.files.wordpress.com/2011/09/maven_eclipse_and_osgi_working_together.pdf";
String destinationDir = "D:\\FileDownload";
fileDownload(fAddress, destinationDir);
}
}
Here, This pdf has 73 pages, and in my folder, it is download as a PDF of 1KB, when opened in Acrobat Reader, it says that the file might be corrupted.
I've also tried the code provided here https://dzone.com/articles/java-how-save-download-file, but the result is same.
please let me know how can I fix this.
Thanks
If you check the downloaded file content, you can see it is html. The server is redirecting the original request to https url. Use url https://singztechmusings.files.wordpress.com/2011/09/maven_eclipse_and_osgi_working_together.pdf instead.
Or use http client with automatic redirect handling, ala http-commons
You define a Variable size = 1024 and use this to define your Buffer.
So logically you can only write 1 KB into it.
But if the input Stream reads more at once it will be lost ... So change your Buffer size to a value which would be able to contain most documents or try to determine the necessary size
I am creating an XML file from my Database and storing it in Internal storage. I require data from XML file into a single string. For which, i am using the following method.
BufferedReader br;
try {
br = new BufferedReader(new FileReader(new File(pathDAR)));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line.trim());
String temp = sb.toString().substring(38);
Log.v("XML TO String", "" + temp);
Log.v("Lengths : ", "" + temp.length() + " " + sb.length());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I have been getting string in the Log, but it seems to be stopping abruptly in the middle.
For e.g. I am supposed to get records string like this. Beginning and ending with database tag.
<database name="DAR.db"><table name="DARWorkDetails"><row><col name="id">1</col><col name="date">05-28-2013</col><col name="visited_city_ID">1264</col><col name="employee_ID">107</col><col name="work_type_ID">1</col><col name="name">null</col><col name="customer_Id">null</col><col name="customer_type_ID">null</col><col name="sub_customer_id">null</col><col name="reason_ID">14</col><col name="reason">ABM SM MEETING</col><col name="remarks">gfhii</col><col name="work_with">211,162</col><col name="IsCustomer">N</col><col name="created_by">107</col><col name="position_id">72</col><col name="designation_Id">3</col><col name="submit_date">05-28-2013</col><col name="IsFinal">null</col></row></table></database>
Instead i have been getting string like this :
<database name="DAR.db"><table name="DARWorkDetails"><row><col name="id">1</col><col name="date">05-28-2013</col><col name="visited_city_ID">1264</col><col name="employee_ID">107</col><col name="work_type_ID">1</col><col name="name">null</col><col name="customer_Id">null</col><col name="customer_type_ID">null</col><col name="sub_customer_id">null</col><col name="reason_ID">14</col><col name="reason">ABM SM MEETING</col><col name="remarks">gfhii</col><col name="work_with">211,162</col><col name="IsCustomer">N</col><col name="created_by">107</col><col name="position_id">72</col><col name="designation_Id">3</col><col name="submit_date">05-28-2013</col><col name="IsFinal">null</co
The String is stopping in the middle. For the sake of example i have only put small example string above. In reality my database has multiple records and i have counted length of the string to around 15640, before abrupt end of the string.
Are there any limitations with StringBuilder in regards to storing characters? I suppose there is memory issue since i have been able to get string fully for records fewer than 10. Problem seems to be arising when records go into upwards of 10. Any help in understanding of solving this issue would be much appreciated.
Please check
It may happen your output is perfect but your Log cat is not displaying it whole.
Log.v("XML TO String", "" + temp);
Log.v("Lengths : ", "" + temp.length() + " " + sb.length());
See reference
I created this class to read strings from a xml file saved in internal storage device, it returns a list , if you want the whole extended string you only need concatenate to link together, if doesn't found the file return an empty list this is all you need to read XML files and parse to Strings, I hope to help!
public class readXMLFile {
private String filePath = "FileStorage";
private String fileName = "File.xml";
private final String tag = "Internal Read Persistence";
File internalFileData;
public readXMLFile() {// default constructor
}
public File getXMLFile(Context context){
File directory = null;
ContextWrapper cw = new ContextWrapper(context);
directory = cw.getDir(filePath, Context.MODE_PRIVATE);
internalFileData = new File(directory, fileName);
if(internalFileData.exists()){
Log.i("ReadXMLFile","File returned");
return internalFileData;
}
else{
Log.i(tag,"the file doesn't exists!");
return null;
}
}
public List<String> readFile(Context context) {
List<String> l = new LinkedList<String>();
try {
File directory = null;
ContextWrapper cw = new ContextWrapper(context);
directory = cw.getDir(filePath, Context.MODE_PRIVATE);
internalFileData = new File(directory, fileName);
if (internalFileData.exists()) {
Log.i("Internal Data", "the root exists!!");
try {
FileInputStream fis = new FileInputStream(internalFileData);
DataInputStream in = new DataInputStream(fis);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
l.add(line);
}
try {
if (in != null) {
in.close();
}
} catch (Exception e) {
Log.i(tag, "Exception closing persistence connection");
}
} catch (Exception e) {
Log.wtf("Fatal Exception", "Exception: " + e.getMessage());
}
} else {
Log.i(tag, "File doesn't exists");
return l;//return empty list
}
} catch (Exception e) {
Log.wtf(tag, "Exception DATA READING: " + e.getMessage());
return l;
}
Log.i(tag, "file found return");
return l;
}
}
I followed a tutorial on writing a basic web crawler in Java and have got something with basic functionality.
At the moment it just retrieves the HTML from the site and prints it to the console.
I was hoping to extend it so it can filter out specifics like the HTML page title and the HTTP status code?
I found this library:
http://htmlparser.sourceforge.net/
... which I think might be able to do the job for me but could I do it without using an external library?
Here's what I have so far:
public static void main(String[] args) {
// String representing the URL
String input = "";
// Check if argument added at command line
if (args.length >= 1) {
input = args[0];
}
// If no argument at command line use default
else {
input = "http://www.my_site.com/";
System.out.println("\nNo argument entered so default of " + input
+ " used: \n");
}
// input test URL and read from file input stream
try {
testURL = new URL(input);
BufferedReader reader = new BufferedReader(new InputStreamReader(
testURL.openStream()));
// String variable to hold the returned content
String line = "";
// print content to console until no new lines of content
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Exception thrown");
}
}
There are definitely tools out there for HTTP communication. However, if you prefer to implement one yourself - look into java.net.HttpURLConnection. It will give you more fine grained control over HTTP communications. Here's a little sample for you:
public static void main(String[] args) throws IOException
{
URL url = new URL("http://www.google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String resp = getResponseBody(connection);
System.out.println("RESPONSE CODE: " + connection.getResponseCode());
System.out.println(resp);
}
private static String getResponseBody(HttpURLConnection connection)
throws IOException
{
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
StringBuilder responseBody = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null)
{
responseBody.append(line + "\n");
}
reader.close();
return responseBody.toString();
}
catch (IOException e)
{
e.printStackTrace();
return "";
}
}