2011-01-21 54 views
2

我正在尝试用泽西1.5写一个POST调用谷歌翻译。这是我的代码:与泽西返回HTTP进行谷歌翻译POST调用HTTP 404

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

提前感谢!

+0

你为什么要使用POST,如果你有一个空的身体吗?尝试使用GET。 – 2011-01-21 08:50:06

+0

我想使用POST的原因是因为否则在翻译非常长的文本时,我将受限于URL的长度。浏览器和服务器实现之间的URL长度似乎有很大差异。 http://www.boutell.com/newfaq/misc/urllength.html – vrutberg 2011-01-21 09:15:33

回答

-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

我怀疑零内容长度的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即可。

+0

感谢您的回复!我已经完成了你写的内容,将params变量作为第二个参数添加到.post()调用中,并删除了我用来设置Content-Length的那一行。但是,这会呈现UniformInterfaceException,表示“返回的响应状态为404”。 – vrutberg 2011-01-24 11:24:02

+0

您仍然需要设置Content-Length以匹配发布数据的长度。我不知道为什么你会得到404回来,但是在任何情况下都需要设置Content-Length。 如果它仍然不起作用,请附上Wireshark的流量捕获,也许这会给我们一个错误的想法。 – RomanK 2011-01-24 11:49:31

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; 
} 
-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) {...