English 中文(简体)
How do I unmarshal a ruby object in java?
原标题:

I have a an object that I d like to grab the contents of in java. The only problem is that is is currently in ruby.

irb(main):050:0> blah
=> "BAh7ByIeYXV0aGVudGljYXRpb25fc3RyYXRlZ2llczAiCXVzZXJpBg%253D%253D-
-0cdecf4edfaa5cbe4693c9fb83b204c1256a54a6"

irb(main):049:0> Marshal.load(Base64.decode64(blah))
=> {"authentication_strategies"=>nil, "user"=>1}

I got the base64 portion allright -- so now everything is in bytes. How would i access that 2nd string? I presume something can be done with jruby but I ve never used it before and would have no clue where to start.

let me elaborate on my problem here.

1) these are cookies that I m trying to share between a servlet on tomcat and a merb app on apache

2) I am not going to be storing them in the database. I have thought about using them in memcached but for other reasons I d like to store them as cookies (yes I m well aware of the security implications involved)

I am currently looking at jruby s Red Bridge/jruby-embed, however since this is only like 70 bytes I need to look at I think it s ridiculous to call up all that overhead for something so simple.

rather than start up a new question.... code I have right now looks like so:

        // using commons
        Base64 b64 = new Base64();
        byte[] decoded = b64.decode(cookie.getValue().getBytes());

        ScriptingContainer container = new ScriptingContainer();
        container.runScriptlet("la = Marshal.load("" + decoded + ""); puts la.to_s;");

obviously this isn t going to work cause marshal is going to check the first 2 bytes of decoded and freak out since it doesn t match jruby s major/minor version....hrmss..

最佳回答

Ok! This is what I did. Let me re-iterate my whole purpose here was to get a cookie session from merb to a servlet running under tomcat.

import java.io.*;
import java.util.*;
import org.jruby.embed.ScriptingContainer;
import org.apache.commons.codec.binary.Base64;
import javax.servlet.*;
import javax.servlet.http.*;

public class process extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   HttpSession session = request.getSession(true);

    PrintWriter out = response.getWriter();
    Cookie[] cookies = request.getCookies();

    for(int i=0; i<cookies.length; i++) {
      Cookie cookie = cookies[i];

      // base64 decode, then un-marshall ruby style...
      // finally figure out what to do with our session secret key
      if(cookie.getName().equals("_session_id")) {
        ScriptingContainer container = new ScriptingContainer();
        container.setWriter(out);
        container.runScriptlet("require  base64 ; puts "" + cookie.getValue() + ""; " +
                              "puts Marshal.load(Base64.decode64("" + cookie.getValue() + "")).to_s; ");
      }                       

    } 

}     
}

Obviously this code can be cleaned up quite a lot -- eg: moving the base64 decoding back to java -- but this will get a cookie from merb. Now I just need to throw the validator in there to make sure this isn t forged.

Thanks for your suggestions everyone!

问题回答

For a solution not involving JRuby, Why don t you serialize the fields you are interested in yourself? For example, saving them as raw strings into a file or to a relational database?

I realize that this may not exactly answer the question but it may be a possibility that you hadn t previously thought of!

EDIT - feydr has made it clear that he was not talking about serializing object data to a file. I presume therefore that the serialization is for inter-process communication, in which case a binary protocol (or any protocol really) delivered via sockets isa good solution and easy to implement. You could do worse than to have a look at Google protocol buffers (it can even do code generation on the Java side).

You may also consider using Google protocol buffers which are available for Ruby and Java (as well as C++ and Python).





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签