2 Stimmen

Ein POST-Aufruf an Google Translate mit Jersey liefert HTTP 404

Ich versuche, einen POST-Aufruf an Google Translate mit Jersey 1.5 zu schreiben. Dies ist mein Code:

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

Wenn ich dies ausführe, erhalte ich nur die folgende Meldung: com.sun.jersey.api.client.UniformInterfaceException: POST [https://www.googleapis.com/language/translate/v2](https://www.googleapis.com/language/translate/v2) returned a response status of 404 .

Ich habe es geschafft, dies mit einem einfachen cURL-Befehl wie folgt zu erreichen:

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](https://www.googleapis.com/language/translate/v2)

Vielen Dank im Voraus!

3voto

RomanK Punkte 1228

Ich vermute, dass POST mit einer Inhaltslänge von Null von einem normalen HTTP-Server nicht akzeptiert wird. Der RFC definiert diesen Fall nicht, aber die Hauptannahme von POST ist, dass Sie einen Nachrichtentext senden.

Die Betrachtung der Google API nennen sie Folgendes

Sie können auch POST verwenden, um die API aufzurufen, wenn Sie mehr Daten in einer einzigen Anfrage senden möchten. Der q-Parameter im POST-Körper muss weniger als 5K Zeichen umfassen. Um POST zu verwenden, müssen Sie den Header X-HTTP-Method-Override verwenden, um der Translate-API mitzuteilen, dass sie die Anfrage als GET behandeln soll (verwenden Sie X-HTTP-Method-Override: GET).

Das bedeutet, dass Sie die Parameter q, source und target nicht in die URL, sondern in den POST-Body einfügen müssen. Ich bin mit der Jersey-API nicht vertraut, aber nach einem kurzen Blick müssen Sie nur params als expliziten zweiten Parameter zum .post-Aufruf hinzufügen, den queryParams()-Aufruf entfernen und die Content-Length richtig einstellen.

2voto

lisak Punkte 20709

Ich denke, der beste und richtige Weg ist dieser

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;
}

-1voto

vrutberg Punkte 1944

Ich wechselte zu Apache HttpClient 4.x und löste es stattdessen wie folgt:

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

}

Ich weiß nicht wirklich, warum das besser funktioniert als Jersey, aber es funktioniert. Danke für den Versuch zu helfen!

-1voto

Daniel Gerber Punkte 2902

Ich war in der Lage, sehr lange Texte wie diesen zu versenden!

Kunde:

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

Server:

@POST
@Produces("text/whatever")
public String textToRdf (
        @FormParam("text") String text) {...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X