我正在尝试使用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
提前致谢!
答案 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) {...