[英]Upload File To Server, java.net.ProtocolException: cannot write request body after response has been read
I want to upload file to server from Android apps. 我想从Android应用程序将文件上传到服务器。 I try this but still cannot upload file to server.
我尝试这样做,但仍然无法将文件上传到服务器。 There's an error in my java.
我的java中有错误。
public class UploadFileActivity extends AppCompatActivity implements View.OnClickListener{
private static final int PICK_FILE_REQUEST = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private String selectedFilePath;
private String SERVER_URL = "http://url.com/mobile/json/upload_file.php";
ImageView ivAttachment;
Button bUpload;
TextView tvFileName;
ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_upload_file);
ivAttachment = (ImageView) findViewById(R.id.ivAttachment);
bUpload = (Button) findViewById(R.id.b_upload);
tvFileName = (TextView) findViewById(R.id.tv_file_name);
ivAttachment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showFileChooser();
}
});
bUpload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedFilePath != null){
dialog = ProgressDialog.show(UploadFileActivity.this,"","Uploading File...",true);
new Thread(new Runnable() {
@Override
public void run() {
uploadFile(selectedFilePath);
}
}).start();
}else{
Toast.makeText(UploadFileActivity.this,"Please choose a File First",Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onClick(View v) {
}
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Choose File to Upload.."),PICK_FILE_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Activity.RESULT_OK){
if(requestCode == PICK_FILE_REQUEST){
if(data == null){
//no data present
return;
}
Uri selectedFileUri = data.getData();
if(Build.VERSION.SDK_INT >= 19) {
selectedFilePath = FilePath.getPath(this, selectedFileUri);
} else {
selectedFilePath = FilePath.getSmartFilePath(this, selectedFileUri);
}
Log.i(TAG,"Selected File Path:" + selectedFilePath);
if(selectedFilePath != null && !selectedFilePath.equals("")){
tvFileName.setText(selectedFilePath);
}else{
Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show();
}
}
}
}
public int uploadFile(final String selectedFilePath){
int serverResponseCode = 0;
HttpURLConnection connection;
DataOutputStream dataOutputStream;
String lineEnd = "\r\n";
String twoHyphens = "--";
final String boundary = "*****";
int bytesRead,bytesAvailable,bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File selectedFile = new File(selectedFilePath);
String[] parts = selectedFilePath.split("/");
String fileName = parts[parts.length-1];
String[] separate = fileName.split(Pattern.quote("."));
final String fileNameDoang = separate[0];
final String fileType = separate[1];
if (!selectedFile.isFile()){
dialog.dismiss();
runOnUiThread(new Runnable() {
@Override
public void run() {
tvFileName.setText("Source File Doesn't Exist: " + selectedFilePath);
}
});
return 0;
}else{
try{
FileInputStream fileInputStream = new FileInputStream(selectedFile);
URL url = new URL(SERVER_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);//Allow Inputs
connection.setDoOutput(true);//Allow Outputs
connection.setUseCaches(false);//Don't use a cached Copy
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("ENCTYPE", "multipart/form-data");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("uploaded_file",selectedFilePath);
int sizeFile = connection.getContentLength();
dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ selectedFilePath + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer,0,bufferSize);
while (bytesRead > 0){
//write the bytes read from inputstream
dataOutputStream.write(buffer,0,bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
bytesRead = fileInputStream.read(buffer,0,bufferSize);
}
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode);
if(serverResponseCode == 200){
runOnUiThread(new Runnable() {
@Override
public void run() {
tvFileName.setText("File Upload completed.\n\n File Name : \n\n" + fileNameDoang + "File Type" + fileType);
}
});
}
fileInputStream.close();
dataOutputStream.flush();
dataOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(UploadFileActivity.this,"File Not Found",Toast.LENGTH_SHORT).show();
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
Toast.makeText(UploadFileActivity.this, "URL error!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(UploadFileActivity.this, "Cannot Read/Write File!", Toast.LENGTH_SHORT).show();
}
dialog.dismiss();
return serverResponseCode;
}
}
}
Get filepath I put in another java. 获取我放入另一个Java的文件路径。 This is the warning and error:
这是警告和错误:
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err: java.net.ProtocolException: cannot write request body after response has been read
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err: at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:223)
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err: at com.sintask.android.ui.UploadFileActivity.uploadFile(UploadFileActivity.java:195)
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err: at com.sintask.android.ui.UploadFileActivity$2$1.run(UploadFileActivity.java:66)
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err: at java.lang.Thread.run(Thread.java:818)
09-30 20:44:50.766 9855-10872/com.sintask.android E/AndroidRuntime: FATAL EXCEPTION: Thread-5234
Process: com.sintask.android, PID: 9855
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
It's because you called getContentLength()
before getting the output stream. 这是因为您在获取输出流之前调用了
getContentLength()
。 Doesn't make any sense. 没有任何意义。 You're uploading, not downloading.
您正在上传,而不是下载。 You don't need the content length, or if you do you don't need it until after you've uploaded the file.
您不需要内容长度,或者如果您不需要,则在上传文件后才需要。
NB available()
is not a correct way to determine the length of a file, or of any input stream. 注意,
available()
不是确定文件或任何输入流长度的正确方法。 Use File.length()
. 使用
File.length()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.