Java - Getting corrupted JPG while uploading using FTP connection? - java

The following code is being used to upload three JPG-Image files using FTP in JAVA.
The files are uploaded and confirmed with a "successful"-message, but the files are corrupted. The small tiny thumbnails-files are partly readable (top quarter).
I tried searching the net and added
setFileType(FTPClient.BINARY_FILE_TYPE);
But the problem still occurs :(
Could somebody have a look at it and give me a hint or advice ?
Code:
package de.immozukunft.programs;
import java.io.*;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.commons.net.ftp.FTPClient;
/**
* This class enables the ability to connect and trasfer data to the FTP server
*/
public class FtpUpDown {
static Locale locale = new Locale("de"); // Locale is set to "de" for
// Germany
static ResourceBundle r = ResourceBundle.getBundle("Strings", locale); // ResourceBundle
// for
// different
// languages
// and
// String
// Management
// FTP-Connection properties
static String host = "IP-address"; //Host
static String username = "username"; // Username
static int port = 21; //Port
static String password = "password"; // Password
/**
* <h3>FTP-connection tester</h3>
*
*/
public static boolean connect() {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.connect(host, port);
ftpClient.login(username, password);
ftpClient.logout();
ftpClient.disconnect();
} catch (Exception e) {
// e.printStackTrace();
System.err.println("Unable to connect"); // TODO String einfügen
return (false);
}
System.out.println("Connection established"); // TODO String einfügen
return (true);
}
/**
* <h3>FTP-Status</h3>
*
* #return
* #throws IOException
*/
static public String getStatus() {
if (connect()) {
return (r.getString("successConnectFTP"));
} else {
return (r.getString("unableToConnectFTP"));
}
}
/**
* <h3>FTP-filelist</h3>
*
* #return String-Array der Dateinamen auf dem FTP-Server
*/
public static String[] list() throws IOException {
FTPClient ftpClient = new FTPClient();
String[] filenameList;
try {
ftpClient.connect(host, port);
ftpClient.login(username, password);
filenameList = ftpClient.listNames();
ftpClient.logout();
} finally {
ftpClient.disconnect();
}
return filenameList;
}
/**
* <h3>FTP-Client-Download:</h3>
*
* #return true falls ok
*/
public static boolean download(String localResultFile,
String remoteSourceFile, boolean showMessages) throws IOException {
FTPClient ftpClient = new FTPClient();
FileOutputStream fos = null;
boolean resultOk = true;
try {
ftpClient.connect(host, port);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.login(username, password);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
fos = new FileOutputStream(localResultFile);
resultOk &= ftpClient.retrieveFile(remoteSourceFile, fos);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.logout();
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {/* nothing to do */
}
ftpClient.disconnect();
}
return resultOk;
}
/**
* <h3>FTP-Client-Upload:</h3>
*
* #param localSourceFile
* The source of local file
* #param remoteResultFile
* Set the destination of the file
* #param showMessages
* If set on TRUE messages will be displayed on the console
* #return true Returns If successfully transfered it will return TRUE, else
* FALSE
*/
public static boolean upload(String localSourceFile,
String remoteResultFile, boolean showMessages) throws IOException {
FTPClient ftpClient = new FTPClient();
FileInputStream fis = null;
boolean resultOk = true;
try {
ftpClient.connect(host, port);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.login(username, password);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
fis = new FileInputStream(localSourceFile);
resultOk &= ftpClient.storeFile(remoteResultFile, fis);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.logout();
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {/* nothing to do */
}
ftpClient.disconnect();
}
return resultOk;
}
// Setter and Getter-methods
public static String getHost() {
return host;
}
public static void setHost(String host) {
FtpUpDown.host = host;
}
public static String getUsername() {
return username;
}
public static void setUsername(String username) {
FtpUpDown.username = username;
}
public static int getPort() {
return port;
}
public static void setPort(int port) {
FtpUpDown.port = port;
}
public static String getPassword() {
return password;
}
public static void setPassword(String password) {
FtpUpDown.password = password;
}
}
greets
THE-E

So I finally figured out what the problem was.
The problem was caused by the order of setFileType(FTPClient.BINARY_FILE_TYPE). It needs to be positioned in the upload()-method after the fis = new FileInputStream(localSourceFile) and before the ftpClient.storeFile(remoteResultFile, fis)
So the full working code is:
import java.io.*;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.commons.net.ftp.FTPClient;
/**
* This class enables the ability to connect and trasfer data to the FTP server
*/
public class FtpUpDown {
static Locale locale = new Locale("de"); // Locale is set to "de" for
// Germany
static ResourceBundle r = ResourceBundle.getBundle("Strings", locale); // ResourceBundle
// for
// different
// languages
// and
// String
// Management
// FTP-Connection properties
static String host = "IP-Address"; // IP-address
static String username = "username"; // Username
static int port = 21; // Port
static String password = "password"; // Password
/**
* <h3>FTP-connection tester</h3>
*
*/
public static boolean connect() {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(host, port);
ftpClient.login(username, password);
ftpClient.logout();
ftpClient.disconnect();
} catch (Exception e) {
// e.printStackTrace();
System.err.println("Unable to connect"); // TODO String einfügen
return (false);
}
System.out.println("Connection established"); // TODO String einfügen
return (true);
}
/**
* <h3>FTP-Status</h3>
*
* #return
* #throws IOException
*/
static public String getStatus() {
if (connect()) {
return (r.getString("successConnectFTP"));
} else {
return (r.getString("unableToConnectFTP"));
}
}
/**
* <h3>FTP-filelist</h3>
*
* #return String-Array der Dateinamen auf dem FTP-Server
*/
public static String[] list() throws IOException {
FTPClient ftpClient = new FTPClient();
String[] filenameList;
try {
ftpClient.connect(host, port);
ftpClient.login(username, password);
filenameList = ftpClient.listNames();
ftpClient.logout();
} finally {
ftpClient.disconnect();
}
return filenameList;
}
/**
* <h3>FTP-Client-Download:</h3>
*
* #return true falls ok
*/
public static boolean download(String localResultFile,
String remoteSourceFile, boolean showMessages) throws IOException {
FTPClient ftpClient = new FTPClient();
FileOutputStream fos = null;
boolean resultOk = true;
try {
ftpClient.connect(host, port);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.login(username, password);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
fos = new FileOutputStream(localResultFile);
resultOk &= ftpClient.retrieveFile(remoteSourceFile, fos);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.logout();
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {/* nothing to do */
}
ftpClient.disconnect();
}
return resultOk;
}
/**
* <h3>FTP-Client-Upload:</h3>
*
* #param localSourceFile
* The source of local file
* #param remoteResultFile
* Set the destination of the file
* #param showMessages
* If set on TRUE messages will be displayed on the console
* #return true Returns If successfully transfered it will return TRUE, else
* FALSE
*/
public static boolean upload(String localSourceFile,
String remoteResultFile, boolean showMessages) throws IOException {
FTPClient ftpClient = new FTPClient();
FileInputStream fis = null;
boolean resultOk = true;
try {
ftpClient.connect(host, port);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.login(username, password);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
fis = new FileInputStream(localSourceFile);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
resultOk &= ftpClient.storeFile(remoteResultFile, fis);
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
resultOk &= ftpClient.logout();
if (showMessages) {
System.out.println(ftpClient.getReplyString());
}
} finally {
try {
if (fis != null) {
fis.close();
}
ftpClient.disconnect();
} catch (IOException e) {/* nothing to do */
}
}
return resultOk;
}
// Setter and Getter-methods
public static String getHost() {
return host;
}
public static void setHost(String host) {
FtpUpDown.host = host;
}
public static String getUsername() {
return username;
}
public static void setUsername(String username) {
FtpUpDown.username = username;
}
public static int getPort() {
return port;
}
public static void setPort(int port) {
FtpUpDown.port = port;
}
public static String getPassword() {
return password;
}
public static void setPassword(String password) {
FtpUpDown.password = password;
}
}

You create a new connection for every operation, and some code paths don't set the "binary file" flag (i.e. the upload and download methods).

setFileType(FTPClient.BINARY_FILE_TYPE) is the right thing to do, but in the code you provided it is only being done in connect(), which isn't called in download().
Even if it was called in download(), disconnect() is called which ends the session.
Bottom line: You need to call setFileType(FTPClient.BINARY_FILE_TYPE) in the download() method and the upload() method after ftpClient.connect(host, port)

Related

Discontinuous FTP download throws "Read timed out" or "Connection reset"

I used FTP and FTPClient in package 'org.apache.commons.net.ftp' to download files from FTP server.
Here is my total example code
public class FtpInput {
private static final Logger LOG = Logger.getLogger(FtpInput.class);
private static final int TIMEOUT = 120000;
private static final String SIZE_COMMAND_REPLY_CODE = "213 ";
/**
* FTPClient
*/
private FTPClient ftpClient;
/**
* FTP size
*/
private long completeFileSize = 0;
protected String ip = "";
protected int port = 21;
protected String user = "";
protected String passwd = "";
protected String path = "";
protected String fileName = "";
/**
* count input bytes
*/
private CountingInputStream is;
/**
* the bytes already processed
*/
private long processedBytesNum;
private byte[] inputBuffer = new byte[1024];
/**
* connect to ftp server and fetch inputStream
*/
public void connect() {
this.ftpClient = new FTPClient();
ftpClient.setRemoteVerificationEnabled(false);
try {
ftpClient.connect(ip, port);
if (!ftpClient.login(user, passwd)) {
throw new IOException("ftp login failed!");
}
if (StringUtils.isNotBlank(path)) {
if (!ftpClient.changeWorkingDirectory(path)) {
ftpClient.mkd(path);
if (!ftpClient.changeWorkingDirectory(path)) {
throw new IOException("ftp change working dir failed! path:" + path);
}
}
}
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setSoTimeout(TIMEOUT);
ftpClient.setConnectTimeout(TIMEOUT);
ftpClient.setDataTimeout(TIMEOUT);
ftpClient.enterLocalPassiveMode();
// keep control channel keep-alive when download large file
ftpClient.setControlKeepAliveTimeout(120);
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException("ftp login failed!", e);
}
// get complete ftp size
completeFileSize = getFtpFileSize();
LOG.info(String.format("ftp file size: %d", completeFileSize));
try {
InputStream ftpis = this.ftpClient.retrieveFileStream(this.fileName);
if (ftpis == null) {
LOG.error("cannot fetch source file.");
}
this.is = new CountingInputStream(ftpis);
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
/**
* readBytes
*
* #return
*/
public byte[] readBytes() {
byte[] bytes = readBytesFromStream(is, inputBuffer);
// the bytes processed
processedBytesNum = is.getCount();
return bytes;
}
/**
* readBytesFromStream
*
* #param stream
* #param inputBuffer
* #return
*/
protected byte[] readBytesFromStream(InputStream stream, byte[] inputBuffer) {
Preconditions.checkNotNull(stream != null, "InputStream has not been inited yet.");
Preconditions.checkArgument(inputBuffer != null && inputBuffer.length > 0);
int readBytes;
try {
readBytes = stream.read(inputBuffer);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (readBytes == inputBuffer.length) {
// inputBuffer is filled full.
return inputBuffer;
} else if (readBytes > 0 && readBytes < inputBuffer.length) {
// inputBuffer is not filled full.
byte[] tmpBytes = new byte[readBytes];
System.arraycopy(inputBuffer, 0, tmpBytes, 0, readBytes);
return tmpBytes;
} else if (readBytes == -1) {
// Read end.
return null;
} else {
// may other situation happens?
throw new RuntimeException(String.format("readBytesFromStream: readBytes=%s inputBuffer.length=%s",
readBytes, inputBuffer.length));
}
}
/**
* fetch the byte size of remote file size
*/
private long getFtpFileSize() {
try {
ftpClient.sendCommand("SIZE", this.fileName);
String reply = ftpClient.getReplyString().trim();
LOG.info(String.format("ftp file %s size reply : %s", fileName, reply));
Preconditions.checkArgument(reply.startsWith(SIZE_COMMAND_REPLY_CODE),
"ftp file size reply: %s is not success", reply);
String sizeSubStr = reply.substring(SIZE_COMMAND_REPLY_CODE.length());
long actualFtpSize = Long.parseLong(sizeSubStr);
return actualFtpSize;
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
public void close() {
try {
if (is != null) {
LOG.info(String.format("already read %d bytes from ftp file %s", is.getCount(), fileName));
is.close();
}
if (ftpClient != null) {
// Must call completePendingCommand() to finish command.
boolean isSuccessTransfer = ftpClient.completePendingCommand();
if (!isSuccessTransfer) {
LOG.error("error happened when complete transfer of ftp");
}
ftpClient.logout();
ftpClient.disconnect();
}
} catch (Throwable e) {
e.printStackTrace();
LOG.error(String.format("Close ftp input failed:%s,%s", e.getMessage(), e.getCause()));
} finally {
is = null;
ftpClient = null;
}
}
public void validInputComplete() {
Preconditions.checkArgument(processedBytesNum == completeFileSize, "ftp file transfer is not complete");
}
/**
* main
*
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String ip = "***.***.***.****";
int port = 21;
String user = "***";
String passwd = "***";
String path = "/home/work";
String fileName = "b.txt";
FtpInput input = new FtpInput();
try {
input.fileName = fileName;
input.path = path;
input.ip = ip;
input.port = port;
input.user = user;
input.passwd = passwd;
// connect to FTP server
input.connect();
while (true) {
// read bytes
byte[] bytes = input.readBytes();
if (bytes == null) {
break;
}
LOG.info("read " + bytes.length + " bytes at :" + new Date(System.currentTimeMillis()));
// Attention: this is used for simulating the process of writing data into hive table
// it maybe consume more than 1 minute;
Thread.sleep(3000);
}
input.validInputComplete();
} catch (Exception e) {
e.printStackTrace();
} finally {
input.close();
}
}
}
here is the exception message:
java.net.SocketTimeoutException: Read timed out
or
java.net.SocketException: Connection reset
at stream.readBytes in method readBytesFromStream
At first, i think it probably caused by writing into hive table slowly, and then the FTP Server closed the connection.
But actually, the speed of writing into hive table is fast enough.
Now, i need your help, how can i fix this problem.
From your comments, it looks like it can take hours before you finish downloading the file.
You cannot reasonably expect an FTP server to wait for you for hours to finish the transfer. Particularly if you are not transferring anything most of the time. You waste server resources and most servers will protect themselves against such abuse.
Your design is flawed.
You should redesign your application to first fully download the file; and import the file only after the download finishes.

Running a Client-Server Chat program

This is one of the most common application scenario that can be found all over the net. and I'm not asking any questions about the java codes that I did because I was successful in running it on my laptop where both the client and server part of the .java file resides. Rather I have had problem getting it to work in between two computers. I tried establishing physical connection using cross-over cable to connect two computers, and did a test to see if file transfers successfully and it did, however, keeping one Server part of the .java file in one computer and client part in the other, I tried to run the server first and then the client but it got a "access denied" error.
For reference here's my two .java files:
/* ChatClient.java */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class ChatClient {
private static int port = 5000; /* port to connect to */
private static String host = "localhost"; /* host to connect to (server's IP)*/
private static BufferedReader stdIn;
private static String nick;
/**
* Read in a nickname from stdin and attempt to authenticate with the
* server by sending a NICK command to #out. If the response from #in
* is not equal to "OK" go bacl and read a nickname again
*/
private static String getNick(BufferedReader in,
PrintWriter out) throws IOException {
System.out.print("Enter your nick: ");
String msg = stdIn.readLine();
out.println("NICK " + msg);
String serverResponse = in.readLine();
if ("SERVER: OK".equals(serverResponse)) return msg;
System.out.println(serverResponse);
return getNick(in, out);
}
public static void main (String[] args) throws IOException {
Socket server = null;
try {
server = new Socket(host, port);
} catch (UnknownHostException e) {
System.err.println(e);
System.exit(1);
}
stdIn = new BufferedReader(new InputStreamReader(System.in));
/* obtain an output stream to the server... */
PrintWriter out = new PrintWriter(server.getOutputStream(), true);
/* ... and an input stream */
BufferedReader in = new BufferedReader(new InputStreamReader(
server.getInputStream()));
nick = getNick(in, out);
/* create a thread to asyncronously read messages from the server */
ServerConn sc = new ServerConn(server);
Thread t = new Thread(sc);
t.start();
String msg;
/* loop reading messages from stdin and sending them to the server */
while ((msg = stdIn.readLine()) != null) {
out.println(msg);
}
}
}
class ServerConn implements Runnable {
private BufferedReader in = null;
public ServerConn(Socket server) throws IOException {
/* obtain an input stream from the server */
in = new BufferedReader(new InputStreamReader(
server.getInputStream()));
}
public void run() {
String msg;
try {
/* loop reading messages from the server and show them
* on stdout */
while ((msg = in.readLine()) != null) {
System.out.println(msg);
}
} catch (IOException e) {
System.err.println(e);
}
}
}
and here's the ChatServer.java:
/* ChatServer.java */
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Hashtable;
public class ChatServer {
private static int port = 5000; /* port to listen on */
public static void main (String[] args) throws IOException
{
ServerSocket server = null;
try {
server = new ServerSocket(port); /* start listening on the port */
} catch (IOException e) {
System.err.println("Could not listen on port: " + port);
System.err.println(e);
System.exit(1);
}
Socket client = null;
while(true) {
try {
client = server.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.err.println(e);
System.exit(1);
}
/* start a new thread to handle this client */
Thread t = new Thread(new ClientConn(client));
t.start();
}
}
}
class ChatServerProtocol {
private String nick;
private ClientConn conn;
/* a hash table from user nicks to the corresponding connections */
private static Hashtable<String, ClientConn> nicks =
new Hashtable<String, ClientConn>();
private static final String msg_OK = "OK";
private static final String msg_NICK_IN_USE = "NICK IN USE";
private static final String msg_SPECIFY_NICK = "SPECIFY NICK";
private static final String msg_INVALID = "INVALID COMMAND";
private static final String msg_SEND_FAILED = "FAILED TO SEND";
/**
* Adds a nick to the hash table
* returns false if the nick is already in the table, true otherwise
*/
private static boolean add_nick(String nick, ClientConn c) {
if (nicks.containsKey(nick)) {
return false;
} else {
nicks.put(nick, c);
return true;
}
}
public ChatServerProtocol(ClientConn c) {
nick = null;
conn = c;
}
private void log(String msg) {
System.err.println(msg);
}
public boolean isAuthenticated() {
return ! (nick == null);
}
/**
* Implements the authentication protocol.
* This consists of checking that the message starts with the NICK command
* and that the nick following it is not already in use.
* returns:
* msg_OK if authenticated
* msg_NICK_IN_USE if the specified nick is already in use
* msg_SPECIFY_NICK if the message does not start with the NICK command
*/
private String authenticate(String msg) {
if(msg.startsWith("NICK")) {
String tryNick = msg.substring(5);
if(add_nick(tryNick, this.conn)) {
log("Nick " + tryNick + " joined.");
this.nick = tryNick;
return msg_OK;
} else {
return msg_NICK_IN_USE;
}
} else {
return msg_SPECIFY_NICK;
}
}
/**
* Send a message to another user.
* #recepient contains the recepient's nick
* #msg contains the message to send
* return true if the nick is registered in the hash, false otherwise
*/
private boolean sendMsg(String recipient, String msg) {
if (nicks.containsKey(recipient)) {
ClientConn c = nicks.get(recipient);
c.sendMsg(nick + ": " + msg);
return true;
} else {
return false;
}
}
/**
* Process a message coming from the client
*/
public String process(String msg) {
if (!isAuthenticated())
return authenticate(msg);
String[] msg_parts = msg.split(" ", 3);
String msg_type = msg_parts[0];
if(msg_type.equals("MSG")) {
if(msg_parts.length < 3) return msg_INVALID;
if(sendMsg(msg_parts[1], msg_parts[2])) return msg_OK;
else return msg_SEND_FAILED;
} else {
return msg_INVALID;
}
}
}
class ClientConn implements Runnable {
private Socket client;
private BufferedReader in = null;
private PrintWriter out = null;
ClientConn(Socket client) {
this.client = client;
try {
/* obtain an input stream to this client ... */
in = new BufferedReader(new InputStreamReader(
client.getInputStream()));
/* ... and an output stream to the same client */
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.err.println(e);
return;
}
}
public void run() {
String msg, response;
ChatServerProtocol protocol = new ChatServerProtocol(this);
try {
/* loop reading lines from the client which are processed
* according to our protocol and the resulting response is
* sent back to the client */
while ((msg = in.readLine()) != null) {
response = protocol.process(msg);
out.println("SERVER: " + response);
}
} catch (IOException e) {
System.err.println(e);
}
}
public void sendMsg(String msg) {
out.println(msg);
}
}
Now, what should I do in order to run this two files from two computers given that I have the physical connection(TCP/IP) setup already??
Thanks in advance... :)
Sounds like it's quite possibly a firewall problem. Have you tried opening a hole in your firewall for port 1001?
Have you also looked at your java.policy and make sure that it is configured to allow local codebase to open sockets?
as mentioned in comment, you should not use port < 1025 for you applications, since they are always used in deamon processes. However you should test your program like this
1) if you get connection refused then you should check the exception properly, whether client program takes time before generating exception ( that mean request is going to server and then it's giving connection refused), in that case you should try java.policy put following in a file named java.policy
grant {
permission java.net.SocketPermission ":1024-65535",
"connect,accept";
permission java.net.SocketPermission ":80", "connect";
permission java.io.FilePermission "", "read,write,delete";
permission java.security.SecurityPermission "";
};
while compiling use this flag -Djava.security.policy=java.policy
more-over you should also try -Djava.rmi.server.hostname=IP, where IP is clien-ip for client.java and server-ip for server.java
2) if you are immediately getting exception at client side then your request is not going outside your pc, so client has some problem.
check the exception properly and post them over here.
3) though i've not got access denied error, but it seems to have port problem that might be solved using policy or port>1024.
post what are you getting now.

java.io.IOException: Stream closed

For multiple image retrieval I am calling a PhotoHelperServlet with an anchor tag to get imageNames(multiple images) as follows
PhotoHelperServlet to get names of Images
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Getting userid from session
Image image = new Image();
image.setUserid(userid);
ImageDAO imageDAO = new ImageDAO();
try {
List<Image> imageId = imageDAO.listNames(image);
if (imageId == null) {
// check if imageId is retreived
}
request.setAttribute("imageId", imageId);
//Redirect it to home page
RequestDispatcher rd = request.getRequestDispatcher("/webplugin/jsp/profile/photos.jsp");
rd.forward(request, response);
catch (Exception e) {
e.printStackTrace();
}
In ImageDAO listNames() method :
public List<Image> listNames(Image image) throws IllegalArgumentException, SQLException, ClassNotFoundException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultset = null;
Database database = new Database();
List<Image> imageId = new ArrayList<Image>();
try {
connection = database.openConnection();
preparedStatement = connection.prepareStatement(SQL_GET_PHOTOID);
preparedStatement.setLong(1, image.getUserid());
resultset = preparedStatement.executeQuery();
while(resultset.next()) {
image.setPhotoid(resultset.getLong(1));
imageId.add(image);
}
} catch (SQLException e) {
throw new SQLException(e);
} finally {
close(connection, preparedStatement, resultset);
}
return imageId;
}
In JSP code:
<c:forEach items="${imageId}" var="imageid">
<img src="Photos/${imageid}">
</c:forEach>
In PhotoServlet doGet() method to get a photo:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String imageid = request.getPathInfo().substring(1);
if(imageid == null) {
// check for null and response.senderror
}
ImageDAO imageDAO = new ImageDAO();
try {
Image image = imageDAO.getPhotos(imageid);
if(image == null) {}
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(image.getPhoto(), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
} catch(Exception e) {
e.printStackTrace();
}
In ImageDAO getPhotos() method
public Image getPhotos(String imageid) throws IllegalArgumentException, SQLException, ClassNotFoundException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultset = null;
Database database = new Database();
Image image = new Image();
try {
connection = database.openConnection();
preparedStatement = connection.prepareStatement(SQL_GET_PHOTO);
preparedStatement.setString(1, imageid);
resultset = preparedStatement.executeQuery();
while(resultset.next()) {
image.setPhoto(resultset.getBinaryStream(1));
}
} catch (SQLException e) {
throw new SQLException(e);
} finally {
close(connection, preparedStatement, resultset);
}
return image;
}
In web.xml
<!-- Getting each photo -->
<servlet>
<servlet-name>Photos Module</servlet-name>
<servlet-class>app.controllers.PhotoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Photos Module</servlet-name>
<url-pattern>/Photos/*</url-pattern>
</servlet-mapping>
<!-- Getting photo names -->
<servlet>
<servlet-name>Photo Module</servlet-name>
<servlet-class>app.controllers.PhotoHelperServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Photo Module</servlet-name>
<url-pattern>/Photo</url-pattern>
</servlet-mapping>
Question:
I am getting following Exception:
java.io.IOException: Stream closed
on this Line:
at app.controllers.PhotoServlet.doGet(PhotoServlet.java:94)
while ((length = input.read(buffer)) > 0) {
The full Exception:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:134)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at java.io.FilterInputStream.read(FilterInputStream.java:90)
at app.controllers.PhotoServlet.doGet(PhotoServlet.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
I'd imagine that the basic code flow is laid out like follows:
try {
Get connection, statement, resultset
Use connection, statement, resultset
Get inputstream of resultset
} finally {
Close resultset, statement, connection
}
try {
Get outputstream
Use inputstream of resultset, outputstream
} finally {
Close outputstream, inputstream of resultset
}
And that the close of the ResultSet has implicitly closed the InputStream. It look like that your JDBC driver does not store the InputStream of the ResultSet fully in memory or on temp storage when the ResultSet is closed. Perhaps the JDBC driver is a bit simplistic, or not well thought designed, or the image is too large to be stored in memory. Who knows.
I'd first figure out what JDBC driver impl/version you're using and then consult its developer documentation to learn about settings which may be able to change/fix this behaviour. If you still can't figure it out, then you'd have to rearrange the basic code flow as follows:
try {
Get connection, statement, resultset
Use connection, statement, resultset
try {
Get inputstream of resultset, outputstream
Use inputstream of resultset, outputstream
} finally {
Close outputstream, inputstream of resultset
}
} finally {
Close resultset, statement, connection
}
Or
try {
Get connection, statement, resultset
Use connection, statement, resultset
Get inputstream of resultset
Copy inputstream of resultset
} finally {
Close resultset, statement, connection
}
try {
Get outputstream
Use copy of inputstream, outputstream
} finally {
Close outputstream, copy of inputstream
}
The first approach is the most efficient, only the code is clumsy. The second approach is memory inefficient when you're copying to ByteArrayOutputStream, or performance inefficient when you're copying to FileOutputStream. If the images are mostly small and do not exceed a megabyte or something, then I'd just copy it to ByteArrayOutputStream.
InputStream input = null;
OutputStream output = null;
try {
input = new BufferedInputStream(resultSet.getBinaryStream("columnName"), DEFAULT_BUFFER_SIZE);
output = new ByteArrayOutputStream();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
for (int length; ((length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} finally {
if (output != null) try { output.close(); } catch (IOException ignore) {}
if (input != null) try { input.close(); } catch (IOException ignore) {}
}
Image image = new Image();
image.setPhoto(new ByteArrayInputStream(output.toByteArray()));
// ...
参考一下:
ImageLoad
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
/**
* 图片加载帮助类(自动异步加载、图片文件缓存、缓存文件管理)
*
* #author n.zhang
*
*/
public class ImageLoad {
private static final String TAG = "imageLoad";// 日志标签
private static final String TAG_REF = TAG + "Ref";
private Executor executor; // 线程池
private int defaultImageID;// 默认图片id
private Context context;// 你懂的
private HashMap<String, PathInfo> cache = new HashMap<String, PathInfo>();// URL
boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); // 路径信息对应表
private LinkedList<PathInfo> use = new LinkedList<PathInfo>();// 已在使用的路径信息队列
private LinkedList<PathInfo> lost = new LinkedList<PathInfo>();// 还未使用的路径信息队列
private LinkedList<PathInfo> original = new LinkedList<PathInfo>();// 初始图片路径信息队列
private int index = 0;// id下标
/**
* 图片加载工具,默认10线程下载,缓存80张图片
*
* #param context
*/
public ImageLoad(Context context) {
this(context, 10, 80, 0);
}
/**
* 图片加载工具
*
* #param context
* 你懂的
* #param threadSize
* 最大线程数
* #param maxCacheSize
* 最大缓存图片数量
* #param defaultImageID
* 默认图片id
*/
public ImageLoad(Context context, int threadSize, int maxCacheSize, int defaultImageID) {
this.context = context;
this.defaultImageID = defaultImageID;
executor = Executors.newFixedThreadPool(threadSize);
loadImagePathInfo();
// 图片信息数量不足不满最大值,以空白图片信息补足。
newImagePathInfo(maxCacheSize);
for (PathInfo pi : original) {
if (null == pi.url) {
lost.offer(pi);
} else {
use.offer(pi);
cache.put(pi.url, pi);
}
}
File dir = null;
if (sdCardExist) {
dir = new File(Environment.getExternalStorageDirectory() + "/t_image/");
} else {
dir = new File(context.getCacheDir() + "/t_image/");
}
// 如果文件存在并且不是目录,则删除
if (dir.exists() && !dir.isDirectory()) {
dir.delete();
}
// 如果目录不存在,则创建
if (!dir.exists()) {
dir.mkdir();
}
}
/**
* 路径信息
*
* #author n.zhang
*
*/
public static class PathInfo {
private int id;// 图片id 此id用于生成存储图片的文件名。
private String url;// 图片url
}
/**
* 获得图片存储路径
*
* #param url
* #return
*/
public PathInfo getPath(String url) {
PathInfo pc = cache.get(url);
if (null == pc) {
pc = lost.poll();
}
if (null == pc) {
pc = use.poll();
refresh(pc);
}
return pc;
}
/**
* #info 微博使用加载数据路径
* #author FFMobile-cuihe
* #date 2012-3-1 下午2:13:10
* #Title: getsPath
* #Description: TODO
* #param#param url
* #param#return 设定文件
* #return PathInfo 返回类型
* #throws
*/
public PathInfo getsPath(String url) {
PathInfo pc = cache.get(url);
if (null == pc) {
pc = lost.peek();
}
// if (null == pc) {
// pc = use.peek();
// refresh(pc);
// }
return pc;
}
public PathInfo getLocalPath(String url) {
PathInfo pc = cache.get(url);
if (null == pc) {
pc = lost.peek();
}
return pc;
}
/**
* 刷新路径信息(从索引中删除对应关系、删除对应的图片文件、获取一个新id)
*
* #param pc
*/
private void refresh(PathInfo pc) {
long start = System.currentTimeMillis();
File logFile = null;
try {
cache.remove(pc.url);
File file = toFile(pc);
file.delete();
logFile = file;
pc.id = index++;
pc.url = null;
} finally {
Log.d(TAG_REF, "ref time {" + (System.currentTimeMillis() - start) + "}; ref {" + logFile + "}");
}
}
/**
* 获得file对象
*
* #param pi
* 路径缓存
* #return
*/
public File toFile(PathInfo pi) {
if (sdCardExist) {
return new File(Environment.getExternalStorageDirectory() + "/t_image/" + pi.id + ".jpg");
} else {
return new File(context.getCacheDir() + "/t_image/" + pi.id + ".jpg");
}
}
/**
* 请求加载图片
*
* #param url
* #param ilCallback
*/
public void request(String url, final ILCallback ilCallback) {
final long start = System.currentTimeMillis();
final PathInfo pc = getPath(url);
File file = toFile(pc);
if (null != pc.url) {
ilCallback.seed(Uri.fromFile(file));
Log.d(TAG, "load time {" + (System.currentTimeMillis() - start) + "}; cache {" + pc.url + "} ");
} else {
pc.url = url;
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (null == msg.obj) {
ilCallback.seed(Uri.EMPTY);
Log.d(TAG, "load lost time {" + (System.currentTimeMillis() - start) + "}; network lost {"
+ pc.url + "}");
} else {
ilCallback.seed((Uri) msg.obj);
Log.d(TAG, "load time {" + (System.currentTimeMillis() - start) + "}; network {" + pc.url + "}");
}
};
};
executor.execute(new DownloadImageTask(pc, file, mHandler));
}
}
private void localRequest(String url, final ILCallback ilCallback) {
final long start = System.currentTimeMillis();
final PathInfo pc = getLocalPath(url);
File file = toFile(pc);
if (null != pc.url) {
ilCallback.seed(Uri.fromFile(file));
Log.d(TAG, "load time {" + (System.currentTimeMillis() - start) + "}; cache {" + pc.url + "} ");
}
}
public void localRequest(String url, ImageView iv) {
localRequest(url, new ImageViewCallback(iv));
}
/**
* 请求加载图片
*
* #param url
* #param iv
*/
public void request(String url, ImageView iv) {
request(url, new ImageViewCallback(iv));
}
/**
* 请求加载图片
*
* #param url
* #param iv
*/
// public void request(String url, ImageButton iv) {
// request(url, new ImageButtonCallbacks(iv));
// }
/**
* 请求加载图片
*
* #param url
* #param iv
*/
// public void request(String url, Button iv) {
// request(url, new ButtonCallbacks(iv));
// }
/**
* 请求加载图片
*
* #param url
* #param iv
*/
public void request(String url, ImageSwitcher iv) {
request(url, new ImageSwitcherCallbacks(iv));
}
/**
* 下载图片任务
*
* #author Administrator
*
*/
private class DownloadImageTask implements Runnable {
private Handler hc;
private PathInfo pi;
private File file;
public DownloadImageTask(PathInfo pi, File file, Handler hc) {
this.pi = pi;
this.file = file;
this.hc = hc;
}
public void run() {
try {
byte[] b = requestHttp(pi.url);
if (null == b) {
throw new IOException("数据为空");
}
writeFile(file, b);
use.offer(pi);
cache.put(pi.url, pi);
Message message = new Message();
message.obj = Uri.fromFile(file);
hc.sendMessage(message);
} catch (IOException e) {
Message message = hc.obtainMessage(0, Uri.EMPTY);
hc.sendMessage(message);
Log.i(TAG, "image download lost.", e);
} catch (RuntimeException e) {
Message message = hc.obtainMessage(0, Uri.EMPTY);
hc.sendMessage(message);
Log.i(TAG, "image download lost.", e);
}
}
}
private void writeFile(File file, byte[] data) throws IOException {
FileOutputStream out = new FileOutputStream(file);
try {
out.write(data);
} finally {
out.close();
}
}
private static byte[] requestHttp(String url) throws IOException {
DefaultHttpClient client = new DefaultHttpClient();
System.gc();
try {
HttpGet get = new HttpGet(url);
HttpResponse res = client.execute(get);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (200 == res.getStatusLine().getStatusCode()) {
res.getEntity().writeTo(baos);
return baos.toByteArray();
} else {
throw new IOException("httpStatusCode:" + res.getStatusLine().getStatusCode());
}
} finally {
client.getConnectionManager().shutdown();
}
}
/**
* 读取图片路径信息
*
* #return
*/
#SuppressWarnings("unchecked")
private void loadImagePathInfo() {
long start = System.currentTimeMillis();
File file = new File(context.getCacheDir() + "/imagePathCache.json");
try {
if (!file.isFile()) {
// 文件不存在。
Log.d(TAG, "path info file does not exist");
imageGc();
return;
}
StringWriter sw = new StringWriter();
char[] buf = new char[1024];
int len;
FileReader fr = new FileReader(file);
while (-1 != (len = fr.read(buf))) {
sw.write(buf, 0, len);
}
fr.close();
JSONObject json = new JSONObject(sw.toString());
Iterator<String> it = json.keys();
while (it.hasNext()) {
String key = it.next();
int id = json.getInt(key);
PathInfo pi = new PathInfo();
pi.url = key;
pi.id = id;
if (index < id) {
index = id;
}
original.add(pi);
}
// 打开文件文件缓存成功
Log.i(TAG, "load path info ok.");
} catch (IOException e) {
Log.i(TAG, "load path info lost - IOException.", e);
imageGc();
} catch (JSONException e) {
Log.i(TAG, "load path info lost - JSONException.", e);
imageGc();
} finally {
if (file.exists()) {
file.delete();
Log.d(TAG, "delete path info file");
}
Log.d(TAG, "load path info time {" + (System.currentTimeMillis() - start) + "}");
}
}
/**
* 如果路径信息加载失败,清理图片目录。
*/
private void imageGc() {
long start = System.currentTimeMillis();
try {
File dir;
if (sdCardExist) {
dir = new File(Environment.getExternalStorageDirectory() + "/t_image/");
} else {
dir = new File(context.getCacheDir() + "/t_image/");
}
if (dir.isDirectory()) {
for (File file : dir.listFiles()) {
file.delete();
// gc
Log.d(TAG_REF, "gc {" + file + "}");
}
}
} finally {
// gc 计时
Log.d(TAG_REF, "gc time {" + (System.currentTimeMillis() - start) + "}");
}
}
private void newImagePathInfo(int max_size) {
for (int i = original.size(); i < max_size; i++) {
PathInfo pc = new PathInfo();
pc.id = index++;
original.add(pc);
}
}
/**
* 保存图片路径信息(如记录,下次程序打开,可读取该记录已存图片继续可用)
*/
public void saveImagePathInfo() {
long start = System.currentTimeMillis();
try {
JSONObject json = new JSONObject();
for (PathInfo pi : use) {
try {
json.put(pi.url, pi.id);
} catch (JSONException e) {
e.printStackTrace();
}
}
File file = new File(context.getCacheDir() + "/imagePathCache.json");
try {
FileWriter fw = new FileWriter(file);
fw.write(json.toString());
fw.close();
Log.i(TAG, "image file info save ok.");
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "image file info save lost.");
file.delete();
}
} finally {
Log.d(TAG, "save time {" + (System.currentTimeMillis() - start) + "}");
}
}
/**
* 图片加载回调
*
* #author n.zhang
*
*/
public static interface ILCallback {
public void seed(Uri uri);
}
private class ImageViewCallback implements ILCallback {
public ImageViewCallback(ImageView iv) {
if (defaultImageID > 0) {
iv.setImageResource(defaultImageID);
}
this.iv = iv;
}
private ImageView iv;
public void seed(Uri uri) {
File f = new File(uri.getPath());
iv.setImageURI(Uri.parse(f.toString()));
f = null;
}
}
// private class ImageButtonCallbacks implements ILCallback {
// public ImageButtonCallbacks(ImageButton iv) {
// if (defaultImageID > 0) {
// iv.setBackgroundResource(defaultImageID);
////iv.setImageResource(defaultImageID);
// }
// this.iv = iv;
// }
//
// private ImageButton iv;
//
// public void seed(Uri uri) {
// iv.setImageURI(uri);
// }
// }
// private class ButtonCallbacks implements ILCallback {
// public ButtonCallbacks(Button iv) {
// if (defaultImageID > 0) {
// iv.setBackgroundResource(defaultImageID);
////iv.setImageResource(defaultImageID);
// }
// this.iv = iv;
// }
//
// private Button iv;
//
// public void seed(Uri uri) {
// iv.setImageURI(uri);
// }
// }
private class ImageSwitcherCallbacks implements ILCallback {
public ImageSwitcherCallbacks(ImageSwitcher iv) {
if (defaultImageID > 0) {
iv.setImageResource(defaultImageID);
}
this.iv = iv;
}
private ImageSwitcher iv;
public void seed(Uri uri) {
iv.setImageURI(uri);
}
}
}
It looks as if the problem is actually not in the code you posted. For some reason the stream input is closed. So you are probably closing the stream in image.getPhoto()

How do I get my map to load in j2me?

My midlet
public void commandAction(Command command, Displayable displayable) {
// write pre-action user code here
if (displayable == form) {
if (command == exitCommand) {
// write pre-action user code here
exitMIDlet();
// write post-action user code here
} else if (command == okCommand) {
try {
// write pre-action user code here
connection = startConnection(5000, myip);
sendMessage("Query,map,$,start,211,Arsenal,!");
String unformattedurl= receiveMessage();
stringItem.setText(stringItem.getText()+" "+unformattedurl);
String url=getURL(unformattedurl,200,200);
Imageloader imageloader=new Imageloader(stringItem,item,url);
Thread thread=new Thread(imageloader);
thread.start();
}
catch(Exception e){
stringItem.setText(stringItem.getText()+" "+e.getMessage());
}
}
}
// write post-action user code here
}
private void sendMessage(String message) throws IOException{
stringItem.setText(stringItem.getText()+2);
DataOutputStream dos = connection.openDataOutputStream();
System.out.println("Sending...."+message);
dos.writeUTF(message);
stringItem.setText(stringItem.getText()+3);
}
public SocketConnection startConnection(int port,String ip) throws IOException{
return (SocketConnection) Connector.open("socket://"+ip+":"+port);
}
public static String[] split(String str,String delim) throws Exception{
String copy=str;
int len=0;
int index = copy.indexOf(delim)+1;
if (index==0){
throw new Exception("Data format not supported");
}
else{
int prev_index=0;
Vector array=new Vector();
//System.out.println(index);
array.addElement(copy.substring(0,index-1));
while (index !=0){
len++;
copy=copy.substring(index);
index = copy.indexOf(delim)+1;
//System.out.println(copy+" "+index);
if (copy.indexOf(delim)==-1){
array.addElement(copy);
}
else{
//System.out.println(0+" "+copy.indexOf(delim));
array.addElement(copy.substring(0,copy.indexOf(delim)));
}
}
String[] array2=new String [array.size()];
for (int i=0;i<array.size();i++){
array2[i]=(String)array.elementAt(i);
//System.out.println(array2[i]);
}
return array2;
}
}
private String receiveMessage() throws IOException{
stringItem.setText(stringItem.getText()+5);
DataInputStream dis = connection.openDataInputStream();
stringItem.setText(stringItem.getText()+6);
return dis.readUTF();
}
private String getURL(String message,int width,int height) throws Exception{
item.setLabel(item.getLabel()+6);
System.out.println("TEst1");
//System.out.println("Formatted message is "+query);
//System.out.println("Getting height......"+label.getMaximumSize().height);
String[] messagearr=split(message,",");
System.out.println("TEst2");
String color,object;
String url="http://maps.google.com/maps/api/staticmap?center=Mauritius&zoom=10&size="+width+"x"+height+"&maptype=roadmap";
//&markers=color:green|label:Bus21|40.702147,-74.015794&markers=color:blue|label:User|40.711614,-74.012318&sensor=false";
String lat,longitude;
System.out.println("TEst3");
if (messagearr[0].equals("query")){
System.out.println("TEst4");
if (messagearr[1].equals("Error")){
String error=messagearr[2];
System.out.println("TEst5"+error);
item.setAltText(error);
item.setLabel("Test"+error);
}
else {
System.out.println("Wrong number");
int startindex=5;
String distance,time;
distance=messagearr[2];
time=messagearr[3];
String name=messagearr[4];
imageLabel="The bus is at :"+time+"min and "+distance +"km from user";
for (int i=startindex;i<messagearr.length;i+=2){
System.out.println("TEst8");
lat=messagearr[i];
longitude=messagearr[i+1];
if (i==startindex){
object="U";
color="Blue";
}
else{
object="B";
color="Green";
}
url=url+"&markers=color:"+color+"|label:"+object+"|"+lat+","+longitude;
item.setLabel(7+url);
System.out.println("TEst10"+" name "+name+" long "+longitude+" lat "+lat+" url "+url );
}
url+="&sensor=false";
System.out.println("Image loaded .... "+url);
return url;
}
}
item.setLabel(item.getLabel()+8);
throw new Exception("Url is wrong");
}
}
public class Imageloader implements Runnable{
StringItem stringitem=null;
ImageItem imageitem=null;
String url=null;
Imageloader(StringItem stringitem,ImageItem imageitem,String url){
this.stringitem=stringitem;
this.imageitem=imageitem;
this.url=url;
stringitem.setText(stringitem.getText()+1);
}
private void loadImage() throws IOException{
stringitem.setText(stringitem.getText()+2);
imageitem.setImage(getImage(url));
}
public Image getImage(String url) throws IOException {
stringitem.setText(stringitem.getText()+3);
HttpConnection hpc = null;
DataInputStream dis = null;
try {
hpc = (HttpConnection) Connector.open(url);
System.out.println(hpc.getResponseMessage());
//hpc.getResponseMessage()
stringitem.setText(stringitem.getText()+" ... "+hpc.getResponseMessage());
int length = (int) hpc.getLength();
System.out.println("Length is "+length);
stringitem.setText(stringitem.getText()+" ... "+length);
byte[] data = new byte[length];
dis = new DataInputStream(hpc.openInputStream());
dis.readFully(data);
return Image.createImage(data, 0, data.length);
} finally {
if (hpc != null)
hpc.close();
if (dis != null)
dis.close();
}
}
public void run() {
try {
stringitem.setText(stringitem.getText()+5);
loadImage();
} catch (IOException ex) {
imageitem.setLabel(ex.getMessage()+5);
ex.printStackTrace();
}
}
}
I am unable to load an image in my mobile phone howerver it works fine using an emulator.
The exception says "Error in HTTP connection"..
and it occurs in the loadImage() method ..
How do I sort this out?
make sure your application has access to make http connection and you have got working connection with your phone

Connecting with different Proxies to specific addresses

I am developing a Java webservice application (with JAX-WS) that has to use two different proxies to establish separated connections to internet and an intranet. As solution I tried to write my own java.net.ProxySelector that returns a java.net.Proxy instance (of type HTTP) for internet or intranet.
In a little test application I try to download webpage via URL.openConnection(), and before I replaced the default ProxySelector with my own. But it results in an exception:
java.net.SocketException: Unknown proxy type : HTTP
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:370)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at sun.net.NetworkClient.doConnect(NetworkClient.java:163)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
at sun.net.www.http.HttpClient.(HttpClient.java:233)
at sun.net.www.http.HttpClient.New(HttpClient.java:306)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:844)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:792)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:703)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1026)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:373)
at norman.test.ProxyTest.conntectToRmViaProxy(ProxyTest.java:42)
at norman.test.ProxyTest.main(ProxyTest.java:65)
Question: "Why tries the application to establish a connection via SOCKS, if my ProxySelector only returns a HTTP Proxy?"
2 Question: "Is there a alternative, to define different proxies for each connection?"
This is my ProxySelector:
public class OwnProxySelector extends ProxySelector {
private Proxy intranetProxy;
private Proxy extranetProxy;
private Proxy directConnection = Proxy.NO_PROXY;
private URI intranetAddress;
private URI extranetAddress;
/* (non-Javadoc)
* #see java.net.ProxySelector#connectFailed(java.net.URI, java.net.SocketAddress, java.io.IOException)
*/
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
// Nothing to do
}
/* (non-Javadoc)
* #see java.net.ProxySelector#select(java.net.URI)
*/
public List select(URI uri) {
ArrayList<Proxy> result = new ArrayList<Proxy>();
if(intranetAddress.getHost().equals(uri.getHost()) && intranetAddress.getPort()==uri.getPort()){
result.add(intranetProxy);
System.out.println("Adding intranet Proxy!");
}
else if(extranetAddress.getHost().equals(uri.getHost()) && extranetAddress.getPort()==uri.getPort()){
result.add(extranetProxy);
System.out.println("Adding extranet Proxy!");
}
else{
result.add(directConnection);
System.out.println("Adding direct connection!");
}
return result;
}
public void setIntranetProxy(String proxyAddress, int proxyPort){
if(proxyAddress==null || proxyAddress.isEmpty()){
intranetProxy = Proxy.NO_PROXY;
}
else{
SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
intranetProxy = new Proxy(Proxy.Type.HTTP, address);
}
}
public void setExtranetProxy(String proxyAddress, int proxyPort){
if(proxyAddress==null || proxyAddress.isEmpty()){
extranetProxy = Proxy.NO_PROXY;
}
else{
SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
extranetProxy = new Proxy(Proxy.Type.HTTP, address);
}
}
public void clearIntranetProxy(){
intranetProxy = Proxy.NO_PROXY;
}
public void clearExtranetProxy(){
extranetProxy = Proxy.NO_PROXY;
}
public void setIntranetAddress(String address) throws URISyntaxException{
intranetAddress = new URI(address);
}
public void setExtranetAddress(String address) throws URISyntaxException{
extranetAddress = new URI(address);
}
}
This is the test class:
public class ProxyTest {
OwnProxySelector ownSelector = new OwnProxySelector();
public ProxyTest(){
ownSelector.setIntranetProxy("intranet.proxy", 8123);
try {
ownSelector.setIntranetAddress("http://intranet:80");
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ownSelector.setExtranetProxy("", 0);
try {
ownSelector.setExtranetAddress("http://www.example.com:80");
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ProxySelector.setDefault(ownSelector);
}
public void conntectToRmViaProxy(boolean internal, String connectAddress){
try {
URL url = new URL(connectAddress);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
System.out.println(conn.getResponseMessage());
}
else{
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
int tmp = reader.read();
while(tmp != -1){
System.out.print((char)tmp);
tmp = reader.read();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){
ProxyTest proxyText = new ProxyTest();
proxyText.conntectToRmViaProxy(true, "http://intranet:80");
}
}
Ok, I have found the problem.
The HttpURLConnection did the OwnProxySelector.select() twice if the requested URL does not contain a port.
At first, HttpURLConnection invoked the select() with an URI, with the Scheme of "http" but no port. The select() checks whether the host address and port are euqal to intranetAddress or extranetAddress. This didn't match, because the port was not given. So the select return a Proxy for a direct connection.
At the second HttpURLConnection invoked the select() with an URI, with the Scheme of "socket" and port 80. So, because the select() checks host address and port, but not the scheme, it returned a HTTP proxy.
Now here is my corrected version of OwnProxySelector. It checks the scheme and sets the default port for HTTP or HTTPS if the port is not given by the URI. Also it asks the Java standard ProxySelector, if no HTTP or HTTPS scheme is given.
public class OwnProxySelector extends ProxySelector {
private ProxySelector defaultProxySelector;
private Proxy intranetProxy;
private Proxy extranetProxy;
private Proxy directConnection = Proxy.NO_PROXY;
private URI intranetAddress;
private URI extranetAddress;
public OwnProxySelector(ProxySelector defaultProxySelector){
this.defaultProxySelector = defaultProxySelector;
}
/* (non-Javadoc)
* #see java.net.ProxySelector#connectFailed(java.net.URI, java.net.SocketAddress, java.io.IOException)
*/
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
// Nothing to do
}
/* (non-Javadoc)
* #see java.net.ProxySelector#select(java.net.URI)
*/
public List select(URI uri) {
ArrayList<Proxy> result = new ArrayList<Proxy>();
if(uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")){
int uriPort = uri.getPort();
// set default http and https ports if port is not given in URI
if(uriPort<1){
if(uri.getScheme().equalsIgnoreCase("http")){
uriPort = 80;
}
else if(uri.getScheme().equalsIgnoreCase("https")){
uriPort = 443;
}
}
if(intranetAddress.getHost().equals(uri.getHost()) && intranetAddress.getPort()==uriPort){
result.add(intranetProxy);
System.out.println("Adding intranet Proxy!");
}
else if(extranetAddress.getHost().equals(uri.getHost()) && extranetAddress.getPort()==uriPort){
result.add(extranetProxy);
System.out.println("Adding extranet Proxy!");
}
}
if(result.isEmpty()){
List<Proxy> defaultResult = defaultProxySelector.select(uri);
if(defaultResult!=null && !defaultResult.isEmpty()){
result.addAll(defaultResult);
System.out.println("Adding Proxis from default selector.");
}
else{
result.add(directConnection);
System.out.println("Adding direct connection, because requested URI does not match any Proxy");
}
}
return result;
}
public void setIntranetProxy(String proxyAddress, int proxyPort){
if(proxyAddress==null || proxyAddress.isEmpty()){
intranetProxy = Proxy.NO_PROXY;
}
else{
SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
intranetProxy = new Proxy(Proxy.Type.HTTP, address);
}
}
public void setExtranetProxy(String proxyAddress, int proxyPort){
if(proxyAddress==null || proxyAddress.isEmpty()){
extranetProxy = Proxy.NO_PROXY;
}
else{
SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
extranetProxy = new Proxy(Proxy.Type.HTTP, address);
}
}
public void clearIntranetProxy(){
intranetProxy = Proxy.NO_PROXY;
}
public void clearExtranetProxy(){
extranetProxy = Proxy.NO_PROXY;
}
public void setIntranetAddress(String address) throws URISyntaxException{
intranetAddress = new URI(address);
}
public void setExtranetAddress(String address) throws URISyntaxException{
extranetAddress = new URI(address);
}
}
But it is curious to me, that the HttpURLConnection did a second invoke of select(), when it got a direct connection Proxy from the first invoke.

Categories

Resources