Как мне демонтировать объект ruby ​​в Java? - PullRequest
4 голосов
/ 19 ноября 2009

У меня есть объект, который я хотел бы захватить содержимое в Java. Единственная проблема в том, что в данный момент он находится в ruby.

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

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

Я получил часть base64, так что теперь все в байтах. Как бы я получить доступ к этой 2-й строке? Я предполагаю, что что-то можно сделать с помощью jruby, но я никогда раньше этим не пользовался и понятия не имел, с чего начать.

Позвольте мне подробнее остановиться на моей проблеме здесь.

1) это куки, которые я пытаюсь разделить между сервлетом на tomcat и приложением merb на apache

2) Я не собираюсь хранить их в базе данных. Я думал об их использовании в memcached, но по другим причинам я хотел бы сохранить их в виде файлов cookie (да, я хорошо знаю о связанных с этим последствиях для безопасности)

В настоящее время я смотрю на красный мост jruby / jruby-embed, однако, поскольку это всего лишь 70 байтов, на которые мне нужно смотреть, я думаю, что смешно вызывать все эти издержки для чего-то такого простого.

вместо того, чтобы начинать новый вопрос .... код, который я сейчас имею, выглядит так:

        // 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;");

очевидно, что это не сработает, потому что маршал будет проверять первые 2 байта декодированных и выходящих из строя, поскольку это не соответствует мажорной / минорной версии jruby .... hrmss ..

Ответы [ 3 ]

3 голосов
/ 19 ноября 2009

Для решения, не связанного с JRuby, почему бы вам не сериализовать интересующие вас поля? Например, сохранить их как необработанные строки в файл или в реляционную базу данных?

Я понимаю, что это не может точно ответить на вопрос, но это может быть вероятность, о которой вы раньше не думали!

РЕДАКТИРОВАТЬ - feydr дал понять, что он не говорил о сериализации данных объекта в файл. Поэтому я предполагаю, что сериализация предназначена для межпроцессного взаимодействия , и в этом случае двоичный протокол (или любой другой протокол), доставленный через сокеты, является хорошим решением и простым в реализации. Вы могли бы сделать хуже, чем взглянуть на буферы протокола Google (он может даже генерировать код на стороне Java).

2 голосов
/ 19 ноября 2009

Хорошо! Это то, что я сделал. Позвольте мне повторить, что вся моя цель здесь состояла в том, чтобы получить сессию cookie от merb до сервлета, работающего под 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; ");
      }                       

    } 

}     
}

Очевидно, что этот код может быть довольно много очищен - например, перенесение декодирования base64 обратно в java - но это получит cookie от merb. Теперь мне просто нужно добавить туда валидатор, чтобы убедиться, что он не подделан.

Спасибо за ваши предложения всем!

1 голос
/ 19 ноября 2009

Вы также можете рассмотреть возможность использования буферов протокола Google, доступных для Ruby и Java (а также C ++ и Python).

...