Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

Jetty9+Java8でProxyサンプルやってみたけどBody部取得できないで困ってます

題名の通りです
ProxyでRequestとResponseを編集したいだけなんですが
このObjに対しrequest.getHeaderNamesなどのHeader情報取得は上手くいくのですが、getParameterValuesやgetParameterメソッドはNullが帰ってきているようで
何も取得できません。
Eclipse4.5 Java1.8.0u51 Jetty9.3.2です
ライブラリパスにはJettyの
jetty-で、client  http  io  proxy  security  server  servlet  util と servlet-api を追加しています

ソースはJava8のものです
java8を使うとjavax.系はLibパス設定しないようです


import java.io.IOException;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.proxy.ConnectHandler;
import org.eclipse.jetty.proxy.ProxyServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

public class sampleJetty {
    public static void main(String[] args) throws Exception{
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
    
        // リクエストを待ち受けるポート番号を設定
        connector.setPort(8888);
        server.addConnector(connector);

        // HTTPS接続をプロキシするため、CONNECTメソッドを処理するハンドラーを設定
        ConnectHandler proxy = new ConnectHandler() {
            @Override
            protected void handleConnect(Request jettyRequest, HttpServletRequest request, HttpServletResponse response, String serverAddress) {
                // ここに任意のロジックを記載すればリクエスト/レスポンスに干渉できる 
                try {
                    System.out.println(getBody8(request));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ServletException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                super.handleConnect(jettyRequest, request, response, serverAddress);
            }
        };
        server.setHandler(proxy);

     // HTTP接続をプロキシするため、ProxyServletを設定
        ServletContextHandler context = new ServletContextHandler(proxy, "/", ServletContextHandler.SESSIONS);
          ServletHolder proxyServletH = new ServletHolder(new ProxyServlet(){
            private static final long serialVersionUID = 12345679L;
            @Override
            protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                // ここに任意のロジックを記載すればリクエスト/レスポンスに干渉できる 
                System.out.println(getBody8(request));
                 super.service(request, response);
            }   
        }); 
        proxyServletH.setInitParameter("blackList", "www.eclipse.org");
        context.addServlet(proxyServletH, "/*");
        proxyServletH.setInitParameter("timeout", String.valueOf(5 * 60 * 1000L));
        
        server.start();
    }
    
    public static String getBody8(HttpServletRequest request) throws IOException, ServletException {
        String body = request.getReader().lines()
                .reduce("", (accumulator, actual) -> accumulator + actual);
        return body;
    }
}

少し動きが変なところもありますがgetBody8以外はJettyのProxyサンプルのまんまです
Proxyとしては稼働できています
ただBody部が取得できないで困ってます
Javaは初心者ですが3週間ほど調べて頑張ってます、OSをLinuxに変えてみたりもしました

考慮漏れがあるのか?なんなのか?
なにかキーワードでもコメントいただけると助かります。

2

回答

4467

閲覧

2件の回答

評価

0

まず、初心者ではないな。

bodyが取得できないのは幾つか原因が考えられる。
一番簡単なのは、methodがpostでない。
次に、既にbodyをパースする処理が行われている(postbody
はstreamである都合上、一度しか確認できない)。

評価

0

ご回答ありがとうございます
この辺り、LINEやYouTUBEサイト以上のものを開発しようと思うとどうしても通らなければならない山場だと感じています。
初心者ではなかなか難しいですが・・・

bodyをパースする処理が行われているとのご指摘
少し参考になりました

たとえばHTTP
上のソースではOverrideしているserviceAPIに網を張っているわけですが
ここで捕まえたときではもうBODY部は空っぽであると
PROXYなので実際受け取ったところは もっと上流にあるのでは?ということですね

でもへんなんですよねContent-Lengthもゼロでリプライされてくるんですよ、なのにProxyできてる

わざとNULLを返すように開発されているとしか思えないと感じるのは、やはり初心者だからでしょうか?

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。