Java:如何使用UrlConnection发布具有授权的请求?

我想生成POST请求到需要authentication的服务器。 我试图用下面的方法:

private synchronized String CreateNewProductPOST (String urlString, String encodedString, String title, String content, Double price, String tags) { String data = "product[title]=" + URLEncoder.encode(title) + "&product[content]=" + URLEncoder.encode(content) + "&product[price]=" + URLEncoder.encode(price.toString()) + "&tags=" + tags; try { URL url = new URL(urlString); URLConnection conn; conn = url.openConnection(); conn.setRequestProperty ("Authorization", "Basic " + encodedString); conn.setDoOutput(true); conn.setDoInput(true); OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); wr.write(data); wr.flush(); // Get the response BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = rd.readLine()) != null) { // Process line... } wr.close(); rd.close(); return rd.toString(); } catch (MalformedURLException e) { e.printStackTrace(); return e.getMessage(); } catch (IOException e) { e.printStackTrace(); return e.getMessage(); } } 

但服务器不会收到授权数据。 应该添加授权数据的行如下:

 conn.setRequestProperty ("Authorization", "Basic " + encodedString); 

和线

 BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); 

也抛出一个IOException。

无论如何,我会非常感激,如果任何人都可以build议上述逻辑的任何修复,以启用使用POST与UrlConnection授权。

但显然它不工作,因为它应该尽pipe如果相同的逻辑用于GET请求一切正常。

这里find一个很好的例子 。 Powerlord是正确的, 下面 ,POST,你需要HttpURLConnection ,而不是。

下面是这样做的代码,

  URL url = new URL(urlString); URLConnection conn = url.openConnection(); conn.setDoOutput(true); conn.setRequestProperty ("Authorization", encodedCredentials); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); writer.write(data); writer.flush(); String line; BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line = reader.readLine()) != null) { System.out.println(line); } writer.close(); reader.close(); 

URLConnection更改为HttpURLConnection ,使其成为POST请求。

  HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); 

build议(…在评论中):

您可能也需要设置这些属性,

 conn.setRequestProperty( "Content-type", "application/x-www-form-urlencoded"); conn.setRequestProperty( "Accept", "*/*" ); 

我没有看到您指定这是POST请求的代码中的任何地方。 然后再一次,你需要一个java.net.HttpURLConnection来做到这一点。

事实上,我强烈推荐使用HttpURLConnection而不是URLConnection ,并使用conn.setRequestMethod("POST"); 看看它是否仍然给你的问题。

对外部应用程序(INSTAGRAM)进行oAuthauthentication步骤3“收到代码后获取令牌”下面的代码只为我工作

值得说明的是,它为我工作,使用一个本地主机的URL与callbackservletconfiguration名称“callback在web.xml和callbackURL注册:例如localhost:8084 / MyAPP / docs / insta / callback

但是在成功完成authentication步骤之后,使用初始方法使用相同的外部站点“INSTAGRAM”执行标记或媒体的GET检索JSON数据不起作用。 在我的servlet内部使用url进行GET,如api.instagram.com/v1/tags/MYTAG/media/recent?access_token=MY_TOKEN只有在这里find的方法工作

感谢所有贡献者

  URL url = new URL(httpurl); HashMap<String, String> params = new HashMap<String, String>(); params.put("client_id", id); params.put("client_secret", secret); params.put("grant_type", "authorization_code"); params.put("redirect_uri", redirect); params.put("code", code); // your INSTAGRAM code received Set set = params.entrySet(); Iterator i = set.iterator(); StringBuilder postData = new StringBuilder(); for (Map.Entry<String, String> param : params.entrySet()) { if (postData.length() != 0) { postData.append('&'); } postData.append(URLEncoder.encode(param.getKey(), "UTF-8")); postData.append('='); postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8")); } byte[] postDataBytes = postData.toString().getBytes("UTF-8"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); conn.setDoOutput(true); conn.getOutputStream().write(postDataBytes); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); StringBuilder builder = new StringBuilder(); for (String line = null; (line = reader.readLine()) != null;) { builder.append(line).append("\n"); } reader.close(); conn.disconnect(); System.out.println("INSTAGRAM token returned: "+builder.toString()); 

发送POST请求调用:

  connection.setDoOutput(true); // Triggers POST. 

如果你想在请求中发送文本使用:

  java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(connection.getOutputStream()); wr.write(textToSend); wr.flush(); 

我今天遇到了这个问题,这里没有一个解决办法工作。 但是, 这里发布的代码适用于POST请求:

 // HTTP POST request private void sendPost() throws Exception { String url = "https://selfsolve.apple.com/wcResults.do"; URL obj = new URL(url); HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); //add reuqest header con.setRequestMethod("POST"); con.setRequestProperty("User-Agent", USER_AGENT); con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345"; // Send post request con.setDoOutput(true); DataOutputStream wr = new DataOutputStream(con.getOutputStream()); wr.writeBytes(urlParameters); wr.flush(); wr.close(); int responseCode = con.getResponseCode(); System.out.println("\nSending 'POST' request to URL : " + url); System.out.println("Post parameters : " + urlParameters); System.out.println("Response Code : " + responseCode); BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); //print result System.out.println(response.toString()); } 

事实certificate,这不是授权问题。 就我而言,这是一个编码问题。 我需要的内容types是application / json,但是来自Java文档:

 static String encode(String s, String enc) Translates a string into application/x-www-form-urlencoded format using a specific encoding scheme. 

编码函数将string转换为application / x-www-form-urlencoded

现在,如果您不设置Content-Type,则可能会收到“415不支持的媒体types”错误。 如果您将其设置为application / json或任何不是application / x-www-form-urlencoded的东西 ,则会出现IOException。 要解决这个问题,只需避免编码方法。

对于这个特定的情况,以下应该工作:

 String data = "product[title]=" + title + "&product[content]=" + content + "&product[price]=" + price.toString() + "&tags=" + tags; 

另一小部分信息可能会对创build缓冲读取器时代码中断的原因有所帮助,因为实际上只有在调用conn.getInputStream()时才会执行POST请求。

在API 22中,使用BasicName值对被取消,而是使用HASMAP。 要了解更多关于HasMap的信息,请访问hasmap developer.android

 package com.yubraj.sample.datamanager; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import com.yubaraj.sample.utilities.GeneralUtilities; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import javax.net.ssl.HttpsURLConnection; /** * Created by yubraj on 7/30/15. */ public class ServerRequestHandler { private static final String TAG = "Server Request"; OnServerRequestComplete listener; public ServerRequestHandler (){ } public void doServerRequest(HashMap<String, String> parameters, String url, int requestType, OnServerRequestComplete listener){ debug("ServerRequest", "server request called, url = " + url); if(listener != null){ this.listener = listener; } try { new BackgroundDataSync(getPostDataString(parameters), url, requestType).execute(); debug(TAG , " asnyc task called"); } catch (Exception e) { e.printStackTrace(); } } public void doServerRequest(HashMap<String, String> parameters, String url, int requestType){ doServerRequest(parameters, url, requestType, null); } public interface OnServerRequestComplete{ void onSucess(Bundle bundle); void onFailed(int status_code, String mesage, String url); } public void setOnServerRequestCompleteListener(OnServerRequestComplete listener){ this.listener = listener; } private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException { StringBuilder result = new StringBuilder(); boolean first = true; for(Map.Entry<String, String> entry : params.entrySet()){ if (first) first = false; else result.append("&"); result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); result.append("="); result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); } return result.toString(); } class BackgroundDataSync extends AsyncTask<String, Void , String>{ String params; String mUrl; int request_type; public BackgroundDataSync(String params, String url, int request_type){ this.mUrl = url; this.params = params; this.request_type = request_type; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... urls) { debug(TAG, "in Background, urls = " + urls.length); HttpURLConnection connection; debug(TAG, "in Background, url = " + mUrl); String response = ""; switch (request_type) { case 1: try { connection = iniitializeHTTPConnection(mUrl, "POST"); OutputStream os = connection.getOutputStream(); BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(os, "UTF-8")); writer.write(params); writer.flush(); writer.close(); os.close(); int responseCode = connection.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { /* String line; BufferedReader br=new BufferedReader(new InputStreamReader(connection.getInputStream())); while ((line=br.readLine()) != null) { response+=line; }*/ response = getDataFromInputStream(new InputStreamReader(connection.getInputStream())); } else { response = ""; } } catch (IOException e) { e.printStackTrace(); } break; case 0: connection = iniitializeHTTPConnection(mUrl, "GET"); try { if (connection.getResponseCode() == connection.HTTP_OK) { response = getDataFromInputStream(new InputStreamReader(connection.getInputStream())); } } catch (Exception e) { e.printStackTrace(); response = ""; } break; } return response; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); if(TextUtils.isEmpty(s) || s.length() == 0){ listener.onFailed(DbConstants.NOT_FOUND, "Data not found", mUrl); } else{ Bundle bundle = new Bundle(); bundle.putInt(DbConstants.STATUS_CODE, DbConstants.HTTP_OK); bundle.putString(DbConstants.RESPONSE, s); bundle.putString(DbConstants.URL, mUrl); listener.onSucess(bundle); } //System.out.println("Data Obtained = " + s); } private HttpURLConnection iniitializeHTTPConnection(String url, String requestType) { try { debug("ServerRequest", "url = " + url + "requestType = " + requestType); URL link = new URL(url); HttpURLConnection conn = (HttpURLConnection) link.openConnection(); conn.setRequestMethod(requestType); conn.setDoInput(true); conn.setDoOutput(true); return conn; } catch(Exception e){ e.printStackTrace(); } return null; } } private String getDataFromInputStream(InputStreamReader reader){ String line; String response = ""; try { BufferedReader br = new BufferedReader(reader); while ((line = br.readLine()) != null) { response += line; debug("ServerRequest", "response length = " + response.length()); } } catch (Exception e){ e.printStackTrace(); } return response; } private void debug(String tag, String string) { Log.d(tag, string); } } 

只要在需要从服务器获取数据的时候调用该函数即可

 HashMap<String, String>params = new HashMap<String, String>(); params.put("action", "request_sample"); params.put("name", uname); params.put("message", umsg); params.put("email", getEmailofUser()); params.put("type", "bio"); dq.doServerRequest(params, "your_url", DbConstants.METHOD_POST); dq.setOnServerRequestCompleteListener(new ServerRequestHandler.OnServerRequestComplete() { @Override public void onSucess(Bundle bundle) { debug("data", bundle.getString(DbConstants.RESPONSE)); } @Override public void onFailed(int status_code, String mesage, String url) { debug("sample", mesage); } }); 

现在完成了。 如果发现任何问题,请评论。

GET和POST请求之间的HTTP授权没有区别,所以我会首先假设其他的错误。 我不build议直接设置授权标题,而是build议使用java.net.Authorization类,但是我不确定它是否解决了您的问题。 也许你的服务器configuration为需要一个不同的授权scheme比“基本”的发布请求?

我正在查看有关如何执行POST请求的信息。 我需要指定mi请求是POST请求,因为我正在使用仅使用POST方法的REST风格的Web服务,并且如果请求不是POST,当我尝试执行请求时,我收到HTTP错误405。我保证我的代码没有错,下一步:我通过GET请求调用我的Web服务创build一个方法,我指出我的应用程序使用该Web服务方法,它的工作原理。 我的代码是下一个:

  URL server = null; URLConnection conexion = null; BufferedReader reader = null; server = new URL("http://localhost:8089/myApp/resources/webService"); conexion = server.openConnection(); reader = new BufferedReader(new InputStreamReader(server.openStream())); System.out.println(reader.readLine());