Solved

Object Serialization between an applet and a servlet

Posted on 2006-06-21
32
541 Views
Last Modified: 2013-11-24
Greetings,

I am running Apahce Tomcat v5.5.

I am writing a Signature panel for use on a tablet PC. The signature is recorded by an applet(client side) and is stored in a BufferedImage class. I need to serialize this class and send it to a servlet so it can be recorded in a database via JDBC or saved to file as a jpeg image(if possible).

Any suggestions?
0
Comment
Question by:jtgraphic
  • 13
  • 9
  • 4
  • +3
32 Comments
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Just write a POST request to the servlet using a URLConnection. ImageIO.write is what you need, as i mentioned in your previous

You can use a simpler version of this:

http://javaalmanac.com/egs/java.net/Post.html
0
 
LVL 14

Expert Comment

by:hoomanv
Comment Utility
here you can find a helper class that simplifies http posting objects for you
http://homel.vsb.cz/~dvo25/reily/books/javaenterprise/servlet/ch10_02.htm#ch10-16733
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Correction to my earlier comment (in case it confuses you) - the example uses a Writer, which you shouldn't. All you should need in essence is:

// Send data
        URL url = new URL("xxxxxxxxxxxxxxxxxx");
        URLConnection conn = url.openConnection();
        conn.setDoOutput(true);
        OutputStream out = conn.getOutputStream();
        ImageIO.write(image, "JPG", out);
        // Make sure 'out' is closed
0
 

Author Comment

by:jtgraphic
Comment Utility
How would you suggest I capture the object on the server side?
0
 
LVL 14

Expert Comment

by:hoomanv
Comment Utility
ObjectInputStream in = new ObjectInputStream(request.getInputStream())
0
 

Author Comment

by:jtgraphic
Comment Utility
I think that's the part that's causing me the most frustration.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
You just read the servlet's input stream. You can then do what you want with it
0
 

Author Comment

by:jtgraphic
Comment Utility
I do that in the doPost function?
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Yes
0
 

Author Comment

by:jtgraphic
Comment Utility
For testing purposes, is there a simple way of writing the captured input to disk to verify that the code is working properly? All of my attempts at writing to disk, other than JDBC, have caused Tomcat to have a fit.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>All of my attempts at writing to disk

Can you show how you were doing that? Writing to a file within the web root will be easier
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
in your servlet:

InputStream in = request.getInputStream();
FileOutputStream out = new FileOutputStream(filename);
byte[] buf = new byte[256];
int nread = 0;
while (-1!=(nread=in.read(buf))) {
   out.write(buf, 0, nread);
}
out.close();
0
 
LVL 30

Expert Comment

by:mayankeagle
Comment Utility
>> of my attempts at writing to disk,

The user-account under which the web-app is running might need permissions to write to the directory where you were trying to write.
0
 

Author Comment

by:jtgraphic
Comment Utility
I'm not sure if the data isn't being received or if the code is incorrect. The end result is that test.jpg is not being created.

This is the ActionPerformed method in the applet from which I attempt to transmit the BufferedImage to the Servlet,

public void actionPerformed( ActionEvent e )
{
      if( e.getSource() == submitButton )
      {
            // Serialize BufferedImage and send to Servlet
            System.out.println("sending data...");
            
            try
            {
                  URL url = new URL( "http://localhost:8080/servlet/SigServ" );
                  URLConnection conn = url.openConnection();
                  conn.setDoOutput( true );
                  OutputStream out = conn.getOutputStream();
                  ImageIO.write( canvas.getImage(), "jpg", out );
                  out.close();
            }
            catch( Exception ex )
            {
                  ex.printStackTrace();
            }
      }
      else if( e.getSource() == clearButton )
      {
            Graphics2D gc = canvas.getImage().createGraphics();
            gc.setColor( Color.white );
            gc.fillRect( 0, 0, canvas.getWidth(), canvas.getHeight() );
            this.repaint();
      }
}

And this is my doPost method from the servlet,

public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
{
      File filename = new File( "C:\\Program Files\\Apache Software Foundation\\Tomcat 5.5\\test.jpg" );
      InputStream in = request.getInputStream();
      FileOutputStream out = new FileOutputStream( filename );

      byte[] buf = new byte[256];
      int nread = 0;

      while ( -1 != ( nread = in.read( buf ) ) )
      {
            out.write(buf, 0, nread);
      }

      out.close();
}
0
 
LVL 30

Expert Comment

by:mayankeagle
Comment Utility
What is the output? Try doing an out.flush () after out.write () though I don't really think its going to help....
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
add some logging to your servlet to get an idea whats happening.

btw, you probably want to send the image on a seperate thread as your gui will be blocked while it is being sent.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 30

Expert Comment

by:mayankeagle
Comment Utility
>> File filename = new File( "C:\\Program Files\\Apache Software Foundation\\Tomcat 5.5\\test.jpg" );

Why not try it like:

File fileName = new File ( "/test.jpg" ) ;
0
 

Author Comment

by:jtgraphic
Comment Utility
>> add some logging to your servlet to get an idea whats happening.

Pardon my ignorance but... How?

>> btw, you probably want to send the image on a seperate thread as your gui will be blocked while it is being sent.

Yeah, that would be nice. However, I'd like to get something working before I start complicating matters.
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
{
     System.out.println("doPost called");
     File filename = new File( "C:\\Program Files\\Apache Software Foundation\\Tomcat 5.5\\test.jpg" );
     InputStream in = request.getInputStream();
     FileOutputStream out = new FileOutputStream( filename );

     byte[] buf = new byte[256];
     int nread = 0;

     while ( -1 != ( nread = in.read( buf ) ) )
     {
         System.out.println("bytes read "+nread);
          out.write(buf, 0, nread);
     }

     out.close();
}


and check the results in your containers log
0
 

Author Comment

by:jtgraphic
Comment Utility
There are 17 different log files in, "C:\Program Files\Apache Software Foundation\Tomcat 5.5\logs" but none of them contain the logging.
0
 

Author Comment

by:jtgraphic
Comment Utility
Is there another location log files are stored?
0
 

Author Comment

by:jtgraphic
Comment Utility
I think the problem is that doPost is not being invoked. How can I get around this?
0
 
LVL 27

Expert Comment

by:rrz
Comment Utility
Did you you check the console ?
Also, did you see
>         System.out.println("sending data...");
from the applet ?
0
 

Author Comment

by:jtgraphic
Comment Utility
Yes, that prints tot he console perfectly.

I found the correct logfile by writing to stdout in doGet. Since writing to stdout from the start of  doPost does not write anything to the file, I must assume that doPost is not being called.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>I found the correct logfile by writing to stdout in doGet.

Actually the code in question shouldn't be causing doGet to be called
0
 

Author Comment

by:jtgraphic
Comment Utility
I know. I did it deliberately to find the correct log file. From looking at some PAQ's I think doPost is the wrong function to place code in anyway. Using,

public void service( HttpServletRequest request, HttpServletResponse response )

I have been able to get the applet and the servlet to talk to each other, at last. I'm able to write to disk as well. I'm having one last problem though. That is that when I use ImageIO.write to write the BufferedImage to the ObjectOutputStream I am not quite sure how to accurately reconstruct it on the server side. I tried using ObjectOutputStream.writeObject but tomcat wouldn't even write to stdout. I'm assuming that BufferedImage doesn't implement Serializable but that's just a guess.

Using object's file IO code, posted above, I get a file of the correct size, in the correct location, with the correct name and file type but the file format is messed up. None of my graphics programs recognize it. Here's the code,

-- In the applet's actionPerformed method --

try
{
      URL url=new URL( "http://localhost:8080/servlet/SigServ" );
      URLConnection con= url.openConnection();

      con.setDoInput ( true );
      con.setDoOutput( true );

      OutputStream out=con.getOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream( out );

      ImageIO.write( canvas.getImage(), "jpg", oos );
      //oos.writeObject( canvas.getImage() );

      InputStream in = con.getInputStream();

      oos.close();
}
catch( Exception ex )
{
      ex.printStackTrace();
}

-- In the servlet's service method --

try
{
      System.out.println("service called");
      File filename = new File( "C:\\test.jpg" );
      InputStream in = request.getInputStream();
      FileOutputStream out = new FileOutputStream( filename );

      PrintWriter outy = response.getWriter();
      outy.println("this is not a test");

      byte[] buf = new byte[256];
      int nread = 0, total_read = 0;

      while ( -1 != ( nread = in.read( buf ) ) )
      {
            total_read += nread;
            out.write( buf, 0, nread );
      }
      System.out.println( "bytes read " + total_read );
      out.close();
}
catch( Exception e )
{
      System.out.println( "try block failed in service method" );
      e.printStackTrace();
}

Any suggestions?
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>I'm assuming that BufferedImage doesn't implement Serializable but that's just a guess.

You're correct. Use the code i mentioned. doPost should work, but service should work too
0
 

Author Comment

by:jtgraphic
Comment Utility
Well that may be true in theory but I tried a dozen different ways and none of the code above called doPost. Perhaps it's a Tomcat 5.5 issue?

At any rate, regardless of which method is used, if BufferedImage isn't serializable, I'm left with the same problem I outlined in my previous post.

Perhaps there's a way to construct a BufferedImage class server side with the data sent by the applet? Any thoughts?
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 500 total points
Comment Utility
>>Perhaps there's a way to construct a BufferedImage class server side with the data sent by the applet? Any thoughts?

Use ImageIO.read
0
 

Author Comment

by:jtgraphic
Comment Utility
As I'm sure you've noticed, I don't work with Java very often.

Thanks for the help!
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
:-)

Your method, whether doPost, or service can be the following btw

public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
{
    image = ImageIO.read(request.getInputStream());
}

How easy is that? ;-)
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
you were helped by more than one person on this question, why did u not split the points?
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
The viewer will learn how to implement Singleton Design Pattern in Java.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now