使用Jersey对Google Translate进行POST调用会返回HTTP 404

时间:2011-01-21 08:22:45

标签: java http post jersey google-translate

我正在尝试使用Jersey 1.5向Google Translate写一个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 个答案:

答案 0 :(得分:3)

我怀疑具有零Content-Length的POST不是普通HTTP服务器可以接受的。 RFC没有定义这种情况,但POST的主要假设是您正在发送消息体。

查看Google API,他们提到了以下内容

  

如果要在单个请求中发送更多数据,也可以使用POST来调用API。 POST正文中的q参数必须小于5K字符。要使用POST,必须使用X-HTTP-Method-Override标头告诉Translate API将请求视为GET(使用X-HTTP-Method-Override:GET)。

这意味着您不需要在URL中添加q,source和target参数,而是需要在POST正文中执行此操作。我不熟悉Jersey API,简单来说你需要将params作为明确的第二个参数添加到.post调用,删除queryParams()调用,并正确设置Content-Length。

答案 1 :(得分: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;
}

答案 2 :(得分:-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"));
    }

}

不知道为什么这比泽西更好,但它确实有效。感谢您的帮助!

答案 3 :(得分:-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) {...