2

JSONを返すAlfrescoWebscriptsを呼び出しています。これは、すべて完全に機能するGETリクエストを使用して行います。ただし、ファイルPOSTを実行すると、Alfrescoサーバーはファイルを正しく受信してJSON応答を返しますが、今回の応答により、Javascriptにコールバックを処理させるのではなく、ブラウザーにダウンロードのプロンプトが表示されます。

現在、これらの呼び出しはすべて、HttpUrlConnectionを使用する「自家製」リバースプロキシ(以下を参照)を経由しています。このプロキシは、すべての通話を別のホストで実行されているAlfrescoにルーティングします。他のすべては正常に機能します(png、テキスト、html、GETリクエスト、さらには認証)。GET応答とPOST応答の両方で、Content-Typeは「application / json; charset=UTF-8」です。

ご回答ありがとうございます。

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;

public class ReverseProxy extends GenericServlet{

public static final String SERVER_URL = "serverURL";
protected String serverURL;
protected boolean debug;

public ReverseProxy(){
}

public void init(ServletConfig config) throws ServletException {
    super.init(config);
    debug = Boolean.valueOf(config.getInitParameter("debug")).booleanValue();
    serverURL = config.getInitParameter("serverURL");
    if(serverURL == null){
        throw new ServletException("ReverseProxy servlet initialization parameter 'serverURL' not defined");
    }
}

public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
    InputStream inputStream;
    OutputStream outputStream;
    Exception exception;
    if(debug){System.out.println("ReverseProxy.service()");}
    HttpServletRequest request;
    HttpServletResponse response;
    try{
        request = (HttpServletRequest)req;
        response = (HttpServletResponse)resp;
    }
    catch(ClassCastException e){
        throw new ServletException("non-HTTP request or response");
    }
    String method = request.getMethod();
    StringBuffer urlBuffer = new StringBuffer();
    urlBuffer.append(serverURL);
    urlBuffer.append(request.getServletPath());
    if(request.getPathInfo() != null)
        urlBuffer.append(request.getPathInfo());
    if(request.getQueryString() != null){
        urlBuffer.append('?');
        urlBuffer.append(request.getQueryString());
    }
    URL url = new URL(urlBuffer.toString());

    //pass authentication
    String user=null, password=null;

    Set entrySet = req.getParameterMap().entrySet();
    Map headers = new HashMap();
    for ( Object anEntrySet : entrySet ) {
        Map.Entry header = (Map.Entry) anEntrySet;
        String key = (String) header.getKey();
        String value = ((String[]) header.getValue())[0];
        if ("user".equals(key)) {
            user = value;
        } else if ("password".equals(key)) {
            password = value;
        }else {
            headers.put(key, value);
        }
    }

    String userpass = null;
    if (user != null && userpass!=null) {
        userpass = user+":"+password;
    }
    String auth = request.getHeader("Authorization");
    if(auth != null){
        if (auth.toUpperCase().startsWith("BASIC ")){
            String userpassEncoded = auth.substring(6);
            userpass = new String(Base64.decodeBase64(userpassEncoded.getBytes()));
        }
    }

    String digest=null;
    if (userpass!=null) {
        if(debug){System.out.println("ReverseProxy found userpass:" + userpass);}
        digest = "Basic " + new String(Base64.encodeBase64((userpass).getBytes()));
    }
    else{
        if(debug){System.out.println("ReverseProxy found no auth credentials");}
    }

    //do connection
    HttpURLConnection connection = null;
    connection = (HttpURLConnection) url.openConnection();
    if (digest != null) {connection.setRequestProperty("Authorization", digest);}

    connection.setRequestMethod(method);
    connection.setDoInput(true);

    if(method.equals("POST")){
        if(request.getHeader("Content-Type") != null){
            if(debug){System.out.println("ReverseProxy Content-Type: " + request.getHeader("Content-Type"));}
            if(debug){System.out.println("ReverseProxy Content-Length: " + request.getHeader("Content-Length"));}
            if(request.getHeader("Content-Type").indexOf("multipart/form-data") != -1){
                connection.setRequestProperty("Content-Type", request.getHeader("Content-Type"));
                connection.setRequestProperty("Content-Length", request.getHeader("Content-Length"));
            }
        }
        connection.setDoOutput(true);
    }
    if(debug){
        System.out.println((new StringBuilder()).append("ReverseProxy: URL=").append(url).append(" method=").append(method).toString());
    }

    //set headers
    Set headersSet = headers.entrySet();
    for ( Object aHeadersSet : headersSet ) {
        Map.Entry header = (Map.Entry) aHeadersSet;
        connection.setRequestProperty((String) header.getKey(), (String) header.getValue());
    }

    connection.connect();
    inputStream = null;
    outputStream = null;
    try{
        if(method.equals("POST")){
            javax.servlet.ServletInputStream servletInputStream = request.getInputStream();
            outputStream = connection.getOutputStream();
            copy(servletInputStream, outputStream);
        }
        response.setContentLength(connection.getContentLength());
        response.setContentType(connection.getContentType());
        if(debug){System.out.println("ReverseProxy Connection Content-Type: " + connection.getContentType());}
        response.setCharacterEncoding(connection.getContentEncoding());
        String cacheControl = connection.getHeaderField("Cache-Control");
        if(cacheControl != null){
            response.setHeader("Cache-Control", cacheControl);
        }
        int responseCode = connection.getResponseCode();
        response.setStatus(responseCode);

        if(responseCode == 401){
            response.setHeader("WWW-Authenticate", "Basic realm=\"Login Required\"");
        }

        for( Iterator i = connection.getHeaderFields().entrySet().iterator() ; i.hasNext() ;){
            Map.Entry mapEntry = (Map.Entry)i.next();
            if(mapEntry.getKey()!=null){
                response.setHeader(mapEntry.getKey().toString(), ((List)mapEntry.getValue()).get(0).toString());
            }
        }

        //if(debug){System.out.println("ReverseProxy Connection Content-Disposition: " + connection.getHeaderField("Content-Disposition"));}

        if(debug){System.out.println((new StringBuilder()).append("ReverseProxy: response code '").append(responseCode).append("' from ").append(url).toString());}
        if (responseCode == 200 || responseCode == 201) {
            inputStream = connection.getInputStream();
        }
        else{
            inputStream = connection.getErrorStream();
        }

        javax.servlet.ServletOutputStream servletOutputStream = response.getOutputStream();
        copy(inputStream, servletOutputStream);
    }
    catch(IOException ex){
        if(debug)
            ex.printStackTrace();
        throw ex;
    }
    finally{
        //if(inputStream == null) goto _L0; else goto _L0
        //break;
    }
    if(inputStream != null){
        inputStream.close();
    }
    if(outputStream != null){
        outputStream.close();
    } 
    inputStream.close();
    if(outputStream != null){
        outputStream.close();
    }
    //throw exception;
}

public long copy(InputStream input, OutputStream output) throws IOException{
    byte buffer[] = new byte[4096];
    long count = 0L;
    for(int n = 0; -1 != (n = input.read(buffer));){
        output.write(buffer, 0, n);
        count += n;
    }

    output.flush();
    if(debug)
        System.err.println((new StringBuilder()).append("copy ").append(count).append(" bytes").toString());
    return count;
}

}

4

2 に答える 2

2

問題はクライアント側か、あなた側の誤解にあると思います。ブラウザ自体がファイルの処理方法を知らないため、コンテンツタイプがのときにブラウザがファイルのダウンロードを要求する場合は正しい動作ですapplication/jsonブラウザは、少なくともtext/*またはのコンテンツタイプに一致するすべてのもののみを表示できますimage/*

通常、JSON応答はJavaScriptによって内部的に処理されます。JavaScriptは、コンテンツタイプが。のajaxical応答を完全に処理できますapplication/jsontext/plainまたはに変更してテストできtext/javascriptます。ブラウザに表示されます(一致するためtext/*)。しかし、JSONの場合、正しいコンテンツタイプは確かにapplication/jsonです。そのままにして、適切なツールを使用してJSONをダウンロード/開く;)

于 2010-03-10T11:49:04.137 に答える
2

解決しました(私のコメントによると)

リクエストがJavascriptから送信されたXmlHttpRequestである場合、「application / json」コンテンツタイプが理解され、ダウンロードは行われません。これは、GETリクエストとPOSTリクエストの両方に当てはまります。ファイルのアップロードを行う場合、JQuery、ExtJSなどのライブラリは、「application / x-www-form-urlencoded」の設定で非表示のフォームを作成し、投稿します(すべてユーザーの操作なしで)。これは、応答がJavascriptではなくブラウザによって解釈されていることを意味します。これを回避する唯一の方法は、返されるJSONのコンテンツタイプを「text / html」に設定することです(「text / plain」ではなく、ブラウザがタグを追加しようとします)。

于 2010-03-12T11:20:21.357 に答える