2

ジャージー1.5でGoogle翻訳へのPOST呼び出しを書き込もうとしています。これは私のコードです:

package main;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;

import javax.ws.rs.core.MultivaluedMap;

public class Main {

    private static String GOOGLE_TRANSLATE_URL = "https://www.googleapis.com/language/translate/v2";

    private static String translateString(String sourceString, String sourceLanguage, String targetLanguage) {
        String response;
        Client c = Client.create();

        WebResource wr = c.resource(GOOGLE_TRANSLATE_URL);
        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
        params.add("q", sourceString);
        params.add("source", sourceLanguage);
        params.add("target", targetLanguage);
        params.add("key", "xxxx");
        wr.header("X-HTTP-Method-Override", "GET");
        response = wr.post(String.class, params);

        return response;
    }

    public static void main(String[] args) {
        System.out.println(translateString("Hello", "en", "sv"));    
    }
}

これを実行すると、返されるのはこれだけです。com.sun.jersey.api.client.UniformInterfaceException: POST https://www.googleapis.com/language/translate/v2 returned a response status of 404

私は次のような単純なcURLコマンドでこれを達成することができました:

curl --header "X-HTTP-Method-Override: GET" -d key=xxxx -d q=Hello -d source=en -d target=sv https://www.googleapis.com/language/translate/v2

前もって感謝します!

4

4 に答える 4

3

Content-Length がゼロの POST は、通常の HTTP サーバーが受け入れるものではないと思います。RFC はこのケースを定義していませんが、POST の主な前提は、メッセージ本文を送信していることです。

Google APIを見ると、次のように言及されています

1 回のリクエストでより多くのデータを送信する場合は、POST を使用して API を呼び出すこともできます。POST 本文の q パラメータは 5K 文字未満にする必要があります。POST を使用するには、X-HTTP-Method-Override ヘッダーを使用して、リクエストを GET として扱うように Translate API に指示する必要があります (X-HTTP-Method-Override: GET を使用します)。

これは、URL に q、source、および target パラメータを追加する代わりに、POST 本文で追加する必要があることを意味します。私はジャージー API に精通していません。簡単に見ると、params を明示的な 2 番目のパラメーターとして .post 呼び出しに追加し、queryParams() 呼び出しを削除し、Content-Length を適切に設定するだけで済みます。

于 2011-01-23T09:23:18.980 に答える
2

最善かつ正しい方法はこれだと思います

private static final String gurl = "www.googleapis.com";
private static final String gpath = "/language/translate/v2/detect";


public String detectLangGooglePost(String text) throws SystemException {

    List<NameValuePair> qparams = new ArrayList<NameValuePair>();
    qparams.add(new BasicNameValuePair("key", key));

    URI uri;
    try {
        uri = URIUtils.createURI("https", gurl, -1, gpath, URLEncodedUtils.format(qparams, "UTF-8"), null);
    } catch (URISyntaxException e) {
        throw new SystemException("Possibly invalid URI parameters", e);
    }

    HttpResponse response = getPostResponse(uri, text);
    StringBuilder builder = getBuilder(response);
    String language = getLanguage(builder);

    return language;
}

private HttpResponse getPostResponse(URI uri, String text) throws SystemException {

    List<NameValuePair> qparams = new ArrayList<NameValuePair>();
    qparams.add(new BasicNameValuePair("q", text));

    HttpResponse response;
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(uri);
    httpPost.addHeader("X-HTTP-Method-Override", "GET");
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(qparams));
        response = httpclient.execute(httpPost);
    } catch (Exception e) {
        throw new SystemException("Problem when executing Google get request", e);
    }

    int sc = response.getStatusLine().getStatusCode();
    if (sc != HttpStatus.SC_OK)
        throw new SystemException("google status code : " + sc);
    return response;
}

private StringBuilder getBuilder(HttpResponse response) throws SystemException {
    HttpEntity entity = response.getEntity();
    if (entity == null)
        throw new SystemException("response entity null");

    StringBuilder builder = new StringBuilder();
    BufferedReader in = null;
    String str;
    try {
        in = new BufferedReader(new InputStreamReader(entity.getContent()));
        while ((str = in.readLine()) != null)
            builder.append(str);
    } catch (IOException e) {
        throw new SystemException("Reading input stream of http google response entity problem", e);
    } finally {
        IOUtils.closeQuietly(in);
    }
    if (builder.length() == 0)
        throw new SystemException("content stream of response entity empty has zero length");
    return builder;
}

private String getLanguage(StringBuilder builder) throws SystemException {
    JSONObject data = null;
    JSONArray detections = null;
    String language = null;

    JSONObject object = (JSONObject) JSONValue.parse(builder.toString());
    if (object == null)
        throw new SystemException("JSON parsing builder object returned null");

    if (object.containsKey("data") == false)
        throw new SystemException("JSONObject doesn't contain data key");
    data = (JSONObject) object.get("data");

    detections = (JSONArray) data.get("detections");
    if (detections == null)
        throw new SystemException("JSON detections is null");

    JSONObject body = (JSONObject) ((JSONArray) detections.get(0)).get(0);
    if (body == null)
        throw new SystemException("detections body is null");

    if (body.containsKey("language") == false)
        throw new SystemException("language key is null");
    language = (String) body.get("language");

    if (language == null || language.equals(unknown))
        throw new SystemException("Google lang detection - resulting language : " + language);
    return language;
}
于 2011-08-17T11:56:37.060 に答える
-1

このような非常に長いテキストを送信することができました!

クライアント:

MultivaluedMap<String,String> formData = new MultivaluedMapImpl();
formData.add("text", text);

WebResource resource = Client.create().resource(getBaseURI()).path("text2rdf");
return resource.type("application/x-www-form-urlencoded").post(String.class, formData);

サーバ:

@POST
@Produces("text/whatever")
public String textToRdf (
        @FormParam("text") String text) {...
于 2012-05-06T17:53:48.420 に答える
-1

Apache HttpClient 4.x に切り替えて、代わりに次のように解決しました。

public class Main {

    private static String GOOGLE_TRANSLATE_URL = "https://www.googleapis.com/language/translate/v2";
    private static String GOOGLE_API_KEY = "xxxx";

    private static String translateString(String sourceString, String sourceLanguage, String targetLanguage) {

        String response = null;

        // prepare call
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(GOOGLE_TRANSLATE_URL+"?q="+sourceString+"&source="+sourceLanguage+"&target="+targetLanguage+"&key="+GOOGLE_API_KEY);
        post.setHeader("X-HTTP-Method-Override", "GET");

        try {

            // make the call
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            response = client.execute(post, responseHandler);

        } catch (IOException e) {
            // todo: proper error handling
        }

        return response;
    }

    public static void main(String[] args) {
        System.out.println(translateString("hello", "en", "sv"));
    }

}

これがJerseyよりもうまく機能する理由はよくわかりませんが、機能します. 助けてくれてありがとう!

于 2011-02-10T20:14:40.483 に答える