2011-01-21 50 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) {...