接着我的博客前后端交互来,使用Post请求完成操作。
get方法从服务器获取数据。post方法向服务器提交数据。
public class MainActivity extends AppCompatActivity {
OkHttpClient okHttpClient=new OkHttpClient();
private TextView textView;
public String string=null;
private String mBaseUrl="http://192.168.43.248:8080/OkHttp_Get/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void doPost(View view){
//post参数并不是拼接到url后面,而是作为请求体发送到服务端的。post方法需要传入一个RequestBody
//get一般是从服务器获取一些数据,即使是传递参数也比较简单。直接拼接到url后面就可以了
// post一般往服务器提交一些数据,提交表单注册信息,他所提交的一些数据比如说参数一般是作为请求体post到服务器端的。需要requestbody构造request。
//如何构造request呢?它也有builder.
textView=(TextView)findViewById(R.id.textView);
//1.拿到okHttpClient对象
FormEncodingBuilder requestBodyBuilder=new FormEncodingBuilder();
//2.构造Request
//2.1构造requestBody
RequestBody requestBody=requestBodyBuilder.add("username","hyman").add("password","123").build();//它只有三个方法,仅仅是为了传递键值对的。
Request.Builder builder=new Request.Builder();
Request request= builder.url(mBaseUrl+"login").post(requestBody).build();
//3 4
executeRequest(request);
}
public void doGet(View view){
textView=(TextView)findViewById(R.id.textView);
//OkHttpClient okHttpClient=new OkHttpClient();
Request.Builder builder=new Request.Builder();
Request request=builder.get().url(mBaseUrl+"login?username=hyman&password=123").build();
executeRequest(request);
}
private void executeRequest(Request request) {
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
L.e("onFailure"+e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Response response) throws IOException {
L.e("onResponse:");
//该方法的返回值是response,所以我们可以通过response拿到相关信息。
string = response.body().string();//想拿到字符串,可以从response-body-string
L.e(string);
/*InputStream is=response.body().byteStream();//即使是一个文件我们这里也可以IO操作。容量也就是我们一个buffer大小。这样就支持大文件下载。*/
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(string);
}
});
}
});
}
}
点击Post按钮,在textview上出现Login success
MyEclipse控制台出现:hyman , 123
使用post请求往服务器传输数据得到hyman 123,然后在前端也就是我们的模拟器上显示内容。
get和简单的post的用法就结束了。
postString方法:
我们在实际开发过程中有一个post Json字符串到服务器。字符串中可能包含了很多信息(业务代码)。
//将String作为requestBody post出去。和doPost唯一不同的是,requestBody的构造。
// doPost是通过 FormEncodingBuilder去构造的,它主要是传递一个post参数的builder,
// 我们要通过一个Builder构造一个requestBody,这个requestBody仅仅是一个字符串。我们不需要构造模式了
public void doPostString(View view){
textView=(TextView)findViewById(R.id.textView);
//传递一个String
RequestBody requestBody= RequestBody.create(MediaType.parse("text/plain;charset=utf-8"),"{username:hyman,password:123}");
Request.Builder builder=new Request.Builder();
Request request= builder.url(mBaseUrl+"postString").post(requestBody).build();
//3 4
executeRequest(request);
}
RequestBody的create方法:
在MyEclipse userAction添加:
//获取传递过来的String对象。postString()方法还需要配置。
public String postString() throws IOException{
HttpServletRequest request=ServletActionContext.getRequest();
ServletInputStream is=request.getInputStream();
//流变成字符串
StringBuilder sb=new StringBuilder();
int len=0;
byte[] buf=new byte[1024];
while((len=is.read(buf))!=-1){
sb.append(new String(buf,0,len));
}
System.out.println(sb.toString());
return null;
}
struts.xml中添加:
<action name="postString" class="com.imooc.action.UserAction" method="postString">
</action>
我们的预期结果是服务器端接收到{username:hyman,password:123}字符串。
运行AS:点击POST STRING按钮。服务器MyEclipse控制台出现 {username:hyman,password:123
我们介绍完了post与传递key value,postString接下来介绍用post传递File到服务端。
public void doPostFile(View view){
textView=(TextView)findViewById(R.id.textView);
File file=new File(Environment.getExternalStorageDirectory(),"banner2.jpg");
if(!file.exists()){
L.e(file.getAbsolutePath()+"not exist!");
return;
}
//mime type
RequestBody requestBody= RequestBody.create(MediaType.parse("application/octet-stream"),file);
Request.Builder builder=new Request.Builder();
Request request= builder.url(mBaseUrl+"postFile").post(requestBody).build();
//3 4
executeRequest(request);
}
public String postFile() throws IOException{
HttpServletRequest request=ServletActionContext.getRequest();
ServletInputStream is=request.getInputStream();
//files在Tomcat/webapps/OkHttp_Get,在这里新建文件夹files.
String dir=ServletActionContext.getServletContext().getRealPath("files");
File file=new File(dir,"banner2.jpg");
FileOutputStream fos=new FileOutputStream(file);
int len=0;
byte[] buf=new byte[1024];
while((len=is.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.flush();
fos.close();
return null;
}
struts.xml:
<action name="postFile" class="com.imooc.action.UserAction" method="postFile">
</action>
把图片上传到服务器有权限问题,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
post上传文件:到此我们已经完成了get post提交参数,post提交String,post提交file。还有post上传文件。了解过web的朋友肯定知道post是upload的一个文件,比如说一个表单,注册信息,填写相关的用户密码上传头像甚至是附件等等。post还可以提交文件。web开发的朋友知道它有一个属性,MultipartFormData必须设置到表单上面。OkHttp是如何上传图片的?
//传递头像。
public void doUpload(View view){
textView=(TextView)findViewById(R.id.textView);
File file=new File(Environment.getExternalStorageDirectory(),"banner2.jpg");
if(!file.exists()){
L.e(file.getAbsolutePath()+"not exist!");
return;
}
//因为我们设计到文件还有参数可以考虑到又是一个构造者模式。其所涉及到的类叫MultipartBuilder.
//"mPhoto"表单域,一般情况它是个input标签,他的type是file,所有的表单域都有个共性他有个name是key,通过key找到所对应的value、比如说表单域,文件的表单域肯定是个文件就代表了那个key。
MultipartBuilder multipartBuilder=new MultipartBuilder();
RequestBody requestBody= multipartBuilder.type(MultipartBuilder.FORM)
.addFormDataPart("username","hyman")
.addFormDataPart("password","123")
.addFormDataPart("mPhoto","hyman.jpg",RequestBody.create(MediaType.parse("application/octet-stream"),file))
.build();
//mime type
Request.Builder builder=new Request.Builder();
Request request= builder.url(mBaseUrl+"uploadInfo").post(requestBody).build();
//3 4
executeRequest(request);
}
<Button
android:id="@+id/button_doUpload"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doUpload"
android:text="Upload" />
public class UserAction extends ActionSupport{
private String username;
private String password;
public File mPhoto;//必须和AS的那个key是一模一样的.可以指定fileName和contentType
public String mPhotoFileName;
public String mPhotoContentType;//没有它会有警告。
public String uploadInfo() throws IOException{
System.out.println(username+","+password);
if (mPhoto==null) {
System.out.print(mPhotoFileName+"is null");
}
String dir=ServletActionContext.getServletContext().getRealPath("files");
File file=new File(dir,mPhotoFileName);
FileUtils.copyFile(mPhoto,file);
return null;
}
}
<action name="uploadInfo" class="com.imooc.action.UserAction" method="uploadInfo">
</action>
结果是:点击Upload按钮,服务器端出现一张图片,图片命名为hyman.jpg ,同时我们拿到username,password。
post下载文件: