Посылка вызова POST в Google Translate с Джерси возвращает HTTP 404 - PullRequest
2 голосов
/ 21 января 2011

Я пытаюсь написать POST-вызов в Google Translate с помощью Jersey 1.5. Это мой код:

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 <a href="https://www.googleapis.com/language/translate/v2" rel="nofollow">https://www.googleapis.com/language/translate/v2</a> 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 <a href="https://www.googleapis.com/language/translate/v2" rel="nofollow">https://www.googleapis.com/language/translate/v2</a>

Заранее спасибо!

Ответы [ 4 ]

3 голосов
/ 23 января 2011

Я подозреваю, что POST с нулевым Content-Length не является чем-то, что нормальный HTTP-сервер примет. RFC не определяет этот случай, но основное предположение POST заключается в том, что вы отправляете тело сообщения.

Глядя на Google API , они упоминают следующее

Вы также можете использовать POST для вызова API, если вы хотите отправить больше данных в одном запросе. Параметр q в теле сообщения POST должен содержать не более 5K символов. Чтобы использовать POST, вы должны использовать заголовок X-HTTP-Method-Override, чтобы указать Translate API для обработки запроса как GET (используйте X-HTTP-Method-Override: GET).

Это означает, что вместо добавления параметров q, source и target в URL, вам нужно сделать это в теле POST. Я не знаком с API Джерси, из краткого обзора вам просто нужно добавить params в качестве явного второго параметра в вызов .post, удалить вызов queryParams () и правильно установить Content-Length.

2 голосов
/ 17 августа 2011

Я думаю, что лучший и правильный путь - это

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;
}
0 голосов
/ 06 мая 2012

Мне удалось отправить очень длинный текст, как этот!

Клиент:

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) {...
0 голосов
/ 10 февраля 2011

Я переключился на 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"));
    }

}

Не знаю, почему это работает лучше, чем на Джерси, но работает.Спасибо за попытку помочь!

...