在上一个文章里面,手机和电脑在同一个局域网里面,可以使用手机访问电脑上的tomcat里面的项目了,我们在上一个文件里面就访问了一个前端的页面。
这里我们希望在软件里面提交一些数据到电脑上的tomcat里面,并不是通过手机端的浏览器,tomcat里面。
这个也用到了之前我们发的文章里面的 安卓发送http请求。 主要就是使用httpURLclient 和 OKhttp这两种方式。
0 http请求讲解
首先我们要知道 http请求分为七种,但是常用的就只有为两类,一个是post请求一个是get请求,
0.1 get请求的数据格式
主要就是分为四个部分,而且get请求传递的参数都是在url里面明文显示的,比如 /?name=tom&id=1
还有一点就是get请求是没有请求体的。
0.2 post请求的数据格式
post请求的数据格式和get请求是一样的,就是多了一个请求体的数据,向服务器传递数据的时候,数据都是在请求体里面。
0.3 二者的区别
主要就是请求参数所在的位置不一样。
1 前后端的代码
我们创建了一个servlet类 ,主要就是得到一下前端的请求数据,然后将数据返回给前端
前端页面,和提交请求以后的服务器打印的数据
这里可以看到我在电脑的浏览器器上访问tomcat是没有问题的
1.1 前端代码
前端页面就放了两个表单,
代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>tomcat安卓</title>
</head>
<body>
<h1>安卓测试网页</h1>
<hr>
用于安卓访问到服务器,安卓手机连接上电脑的热点,保证手机和电脑处于同一个局域网下面。<br>
这个网页在电脑浏览器上面的url是: http://localhost:8080/ <br>
但是安卓手机在浏览器网址里面输入这个网址的时候并不能访问到我们的这个index.jsp页面。<br>
然后我又查询了一下,电脑的局域网地址是192.168.137.1 <br>
<img src="img/ip.png" width="400px" alt=""> <br>
现在我在手机端的浏览器里面输入网址 http://192.168.137.1:8080/ 可以访问到这个index.jsp页面 <br>
<img src="img/android.jpg" width="500" alt=""><br>
<%--我就在这里写了一个简单的页面--%>
</body>
</html>
1.2 服务器后端代码
服务器 servelt的代码,其实就是获得post和get方式提交过来的参数。
在idea的控制台进行打印,主要就是打印出来 客户端的一些信息
其中里面重要的有两个地方
一个是得到客户端提交过来的参数
//4. 获得post方式或者get方式的请求参数
String postMethodPara1 = request.getParameter(“name”);
String postMethodPara2 = request.getParameter(“password”);
//4. 获得get方式的请求参数
String getMethodPara = request.getQueryString() ;
System.out.println(“ 获得get方式的请求参数:”+getMethodPara);
一个就是得到客户端传递过来的http请求头里面的数据
//8.1 得到请求头里面的数据 //4.1 得到请求头里面的数据
Enumeration
//遍历这些请求头
System.out.println(“*请求头数据**“);
while(headernames.hasMoreElements()){
String name = headernames.nextElement();<br /> String value = request.getHeader(name);<br /> System.out.println(name+"-----"+value);
}
package web;
import jdk.nashorn.internal.ir.RuntimeNode;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
@WebServlet("/myServlet")
public class Servlet_android extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//在pc端,只能通过form表单来发送post请求 还需要注意的就是 post请求的时候可能会出现乱码
request.setCharacterEncoding("utf-8");
System.out.println("服务器收post到请求.....");
//1.得到请求的 方法
String method = request.getMethod() ;
System.out.println("请求方式是:"+method);
//2.获取虚拟目录
String contextPath = request.getContextPath();
System.out.println("虚拟目录:"+contextPath);
//3.获得Servlet的路径
String servletPath = request.getServletPath();
System.out.println("获得Servlet的路径:"+servletPath);
//4. 获得post方式的请求参数
String postMethodPara1 = request.getParameter("name");
String postMethodPara2 = request.getParameter("password");
System.out.println(" 获得post方式的请求参数:"+postMethodPara1+postMethodPara2);
//5. 获取请求的URL 和URI
String getURI = request.getRequestURI();
System.out.println("获取请求的URI:"+getURI);
StringBuffer getURL = request.getRequestURL();
System.out.println(" 获取请求的URL:"+getURL);
//6. 获得客户端的协议版本
String ProtocolVersion = request.getProtocol();
System.out.println("获得客户端的协议版本:"+ProtocolVersion);
//7.获得客户端的IP地址
String clientIp = request.getRemoteAddr();
System.out.println("获得客户端的IP地址:"+clientIp);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("post收到数据---- "+postMethodPara1+postMethodPara2);
//8.1 得到请求头里面的数据 //4.1 得到请求头里面的数据
Enumeration<String> headernames = request.getHeaderNames(); // 得到所有的请求头
//遍历这些请求头
System.out.println("***************************请求头数据**********************");
while(headernames.hasMoreElements()){
String name = headernames.nextElement();
String value = request.getHeader(name);
System.out.println(name+"-----"+value);
}
System.out.println("****************************************************************");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决接收数据乱码
request.setCharacterEncoding("utf-8");
System.out.println("服务器收get到请求.....");
//1.得到请求的 方法
String method = request.getMethod() ;
System.out.println("请求方式是:"+method);
//2.获取虚拟目录
String contextPath = request.getContextPath();
System.out.println("虚拟目录:"+contextPath);
//3.获得Servlet的路径
String servletPath = request.getServletPath();
System.out.println("获得Servlet的路径:"+servletPath);
//4. 获得get方式的请求参数
String getMethodPara = request.getQueryString() ;
System.out.println(" 获得get方式的请求参数:"+getMethodPara);
//5. 获取请求的URL 和URI
String getURI = request.getRequestURI();
System.out.println("获取请求的URI:"+getURI);
StringBuffer getURL = request.getRequestURL();
System.out.println(" 获取请求的URL:"+getURL);
//6. 获得客户端的协议版本
String ProtocolVersion = request.getProtocol();
System.out.println("获得客户端的协议版本:"+ProtocolVersion);
//7.获得客户端的IP地址
String clientIp = request.getRemoteAddr();
System.out.println("获得客户端的IP地址:"+clientIp);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("get收到数据---- "+ getMethodPara);
//8.1 得到请求头里面的数据 //4.1 得到请求头里面的数据
Enumeration<String> headernames = request.getHeaderNames(); // 得到所有的请求头
//遍历这些请求头
System.out.println("***************************请求头数据**********************");
while(headernames.hasMoreElements()){
String name = headernames.nextElement();
String value = request.getHeader(name);
System.out.println(name+"-----"+value);
}
System.out.println("****************************************************************");
}
}
2 使用手机的浏览器去访问tomcat
首先时候你要保证,手机的和电脑是在同一个局域网下(手机连上电脑的热点,或者电脑连上手机的热点就可以了),这样才可以通过手机的浏览器访问到tomcat
我们在电脑浏览器访问tomcat的时候 的网址是;http://localhost:8080/form.jsp
但是我在手机浏览器上是不可以用这个网址的,我们要知道电脑的局域网ip
可以看到电脑的局域网的ip是 192.168.137.1 ,所以手机浏览器的访问地址应该是:http://192.168.137.1:8080/form.jsp
我打开手机浏览器输入数据
发送请求以后收到了服务器返回来的数据
然后我们在看一下服务器打印的数据,看到服务器确实也收到了手机浏览器输入的数据
3 用手机的APP去访问tomcat
2里面是使用手机浏览器发送的http请求,但是我们在 前面的文章Android发送Http里面讲了使用 HttpUrlClient和OKhttp发送http请求,那么我们是不是也可以这样来请求我们的本地tomcat???
开始试试吧,首先还是要保证我们的手机和电脑是在同一个局域网下面,因为我们没有买云服务器,
3.1 使用HttpUrlClient 发送http
安卓端
写两个按钮,一个textview 一个发送get请求,一个发送post请求,textView将服务器返回的数据展示一下。
界面展示
代码展示
public class MainActivity extends AppCompatActivity {
private TextView textView ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button getButton = findViewById(R.id.Bt_get);
Button postButton = findViewById(R.id.Bt_post);
textView = findViewById(R.id.ShowResp);
getButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendGetWithHttpURLConn();
}
});
postButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendPostWithHttpURLConn();
}
});
}
/**
* 总结一下
*
* 1.发送http请求使用到了网络操作,肯定要添加网络权限
* 2. 因为我们自己的服务器使用的是 http 不安全的协议 Android 10 以后默认可能访问不了这个http协议,可以访问https
* 发送http请求可能会报错 Cleartext HTTP traffic to 192.168.137.1 not permitted
* 解决方法 https://blog.csdn.net/qq_32534441/article/details/103529449
* 3. 不管是get方法还是post方法,都可以添加参数, 但是添加参数的时候分为向 url里面添加参数和 向 请求头里面添加参数
*
* 3.1 向 url里面添加参数
* get方法直接放到url里面就可以了。
* post 使用
* DataOutputStream out = new DataOutputStream(connection.getOutputStream());
* out.writeBytes("name=luoadmine&password=adf45a4sdf");
*
* 添加到url里面的话 在服务端使用
* request.getParameter("name"); post,get方法都可以使用这个方法得到url里面参数的值
* //. 获得get方式的请求参数
* String getMethodPara = request.getQueryString() ;
*
* 3.2想请求头里面添加参数
* 都是使用 setRequestProperty(key,value )
* //服务器哪里是要通过 得到遍历请求头才可以拿到setRequestProperty("data2","asdfasdf22"); 里面的参数的
* connection.setRequestProperty("data","this is a data .........haiyang");
* connection.setRequestProperty("data2","asdfasdf22");
*
* 请求头里面的参数 只有通过遍历请求头才可以得到 使用 3,1里面的方法是得到不到的
*
*/
/**
* 发送get请求的方法
*/
private void sendGetWithHttpURLConn(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null ;
BufferedReader reader = null ;
try {
//url里面的参数是可以拿到的
URL url = new URL("http://192.168.137.1:8080/myServlet?name=haiyang&password=4a5sd4f");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
//但是这里设置的参数是添加到 请求头里面了,在服务器哪里使用request.getQueryString() ; 是拿不到数据的
//服务器哪里是要通过 得到遍历请求头才可以拿到setRequestProperty("data2","asdfasdf22"); 里面的参数的
connection.setRequestProperty("data","this is a data .........haiyang");
connection.setRequestProperty("data2","asdfasdf22");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
//对输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line ;
while ((line = reader.readLine()) != null){
response.append(line);
};
//将数据显示出来
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(response.toString());
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//释放资源
if(reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null){
connection.disconnect();
}
}
}
}).start();
}
/**
* 发送post请求的方法
*/
private void sendPostWithHttpURLConn(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null ;
BufferedReader reader = null ;
try {
//URL url = new URL("http://192.168.137.1:8080/myServlet?name=haiyang&password=4a5sd4f");
URL url = new URL("http://192.168.137.1:8080/myServlet");
//因为是post方法所以不能在url里面拼接参数
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
//设置要传递的参数 当然get方法在url里面拼接上参数也是可以的
connection.setRequestProperty("data","this is a data .........haiyang");
connection.setRequestProperty("data2","asdfasdf22");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
//注意设置参数的时候的 语句要放到下面,位置不对会报错!!!!!!!!!!!!
//设置参数就是 这个设置参数的方方法,就相当于是get方法里面的 拼接到 url里面
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("name=luoadmine&password=adf45a4sdf");
InputStream in = connection.getInputStream();
//对输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line ;
while ((line = reader.readLine()) != null){
response.append(line);
};
//将数据显示出来
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(response.toString());
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//释放资源
if(reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null){
connection.disconnect();
}
}
}
}).start();
}
}
注解:
总结一下
1.发送http请求使用到了网络操作,肯定要添加网络权限
2. 因为我们自己的服务器使用的是 http 不安全的协议 Android 10 以后默认可能访问不了这个http协议,可以访问https
发送http请求可能会报错 Cleartext HTTP traffic to 192.168.137.1 not permitted
* 解决方法 https://blog.csdn.net/qq_32534441/article/details/103529449
在清单文件里面添加这一句,让我们可以访问http开始的url,不添加这一句的话只能访问https发送的url
* 3. 不管是get方法还是post方法,都可以添加参数, 但是添加参数的时候分为向 url里面添加参数和 向 请求头里面添加参数<br /> *<br /> * 3.1 向 url里面添加参数<br /> * get方法直接放到url里面就可以了。<br /> * post 使用<br /> * DataOutputStream out = new DataOutputStream(connection.getOutputStream());<br /> * out.writeBytes("name=luoadmine&password=adf45a4sdf");<br /> *<br /> * 添加到url里面的话 在服务端使用<br /> * request.getParameter("name"); post,get方法都可以使用这个方法得到url里面参数的值<br /> * //. 获得get方式的请求参数<br /> * String getMethodPara = request.getQueryString() ;<br /> *<br /> * 3.2想请求头里面添加参数<br /> * 都是使用 setRequestProperty(key,value )<br /> * //服务器哪里是要通过 得到遍历请求头才可以拿到setRequestProperty("data2","asdfasdf22"); 里面的参数的<br /> * connection.setRequestProperty("data","this is a data .........haiyang");<br /> * connection.setRequestProperty("data2","asdfasdf22");<br /> *<br /> * 请求头里面的参数 只有通过遍历请求头才可以得到 使用 3,1里面的方法是得到不到的<br /> *<br /> */
3.2 使用OKhttp发送http请求
前面我们也讲过OKHttp发送http请求。这里我们使用OKHttp访问一下自己的服务器
安卓的界面
代码
//使用okhttp发送http请求首先就是要导入 OkHttp的包 implementation 'com.squareup.okhttp3:okhttp:3.4.1'
//还有就是要和使用HttpURLConnection的时候一样,添加一句话让手机可以请求http开头的url
public class MainActivity2 extends AppCompatActivity {
private Button bt_get , bt_post;
private TextView textView ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
bt_get = findViewById(R.id.Bt_get_okhttp);
bt_post =findViewById(R.id.Bt_post_okhttp) ;
textView = findViewById(R.id.ShowRespOKhttp);
bt_get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendGetWithOKHttp() ;
}
});
bt_post.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendPostWithOKHttp();
}
});
}
/**
* OKHttp发送get请求的方法
*/
private void sendGetWithOKHttp(){
new Thread(new Runnable() {
@Override
public void run() {
//得到Okhttp对象
OkHttpClient client = new OkHttpClient();
// //1 创建一个请求体构造器 相当于是一个form表单 ,通过add方法想form表单里面添加数据
// FormBody.Builder formBuilder = new FormBody.Builder();
// formBuilder.add("name","dasdfasd");
// formBuilder.add("age","1234133");
// //表单构造器正式生成 请求体 一会将请求体设置给http请求 对象
// RequestBody requestBody =formBuilder.build();
//
// //2 创建一个请求构造器 我们可以给请求构造器 添加请求头的数据,添加请求地址
// Request.Builder requestBuilder = new Request.Builder();
// //添加请求地址
// requestBuilder.url("http://192.168.137.1:8080/myServlet");
// requestBuilder.get(); //默认就是get方法了。
// requestBuilder.patch(requestBody);
// //向请求头里面添加数据
// requestBuilder .header("headerData","this is my header data ") ; //这个是往请求头里面放置消息
// //正式生成请求
// Request request = requestBuilder.build();
//**** get请求好像没有办法使用上面的这样的方法 向URl里面添加参数
//上面两步可以合成一步,将请求参数添加到 url里面
//get方式好像只能 在url里面添加参数 使用formBuilder好像没有办法 给get方式设置参数
Request request = new Request.Builder()
.url("http://192.168.137.1:8080/myServlet?name=haoo&password=asdfa")
//.patch(requestBody) //这好像是get方式往url里面添加请求参数
.header("headerData","this is my header data ") //这个是往请求头里面放置消息
.build();
// 调用客户端,给服务器”打电话“ 接收服务器返回来的数据
String resp = "" ;
try {
Response response = client.newCall(request).execute();
//回来的数据转为字符串
resp = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
//只能在主线程里面更新UI
String finalResp = resp;
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(finalResp);
}
});
}
}).start();
}
/**
* okhttp发送post请求
*/
private void sendPostWithOKHttp(){
new Thread(new Runnable() {
@Override
public void run() {
//得到Okhttp对象
OkHttpClient client = new OkHttpClient();
//1 创建一个请求体构造器 相当于是一个form表单 ,通过add方法想form表单里面添加数据
FormBody.Builder formBuilder = new FormBody.Builder();
formBuilder.add("name","dopost dasdfasd");
formBuilder.add("password","1234133");
//表单构造器正式生成 请求体 一会将请求体设置给http请求 对象
RequestBody requestBody =formBuilder.build();
//2 创建一个请求构造器 我们可以给请求构造器 添加请求头的数据,添加请求地址
Request.Builder requestBuilder = new Request.Builder();
//添加请求地址
requestBuilder.url("http://192.168.137.1:8080/myServlet");
requestBuilder.post(requestBody); //使用post方式提交
//向请求头里面添加数据
requestBuilder .header("headerData","this is my header data ") ; //这个是往请求头里面放置消息
//正式生成请求
Request request = requestBuilder.build();
// 调用客户端,给服务器”打电话“ 接收服务器返回来的数据
String resp = "" ;
try {
Response response = client.newCall(request).execute();
//回来的数据转为字符串
resp = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
//只能在主线程里面更新UI
String finalResp = resp;
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(finalResp);
}
});
}
}).start();
}
}
发送的结果
服务器收到的数据
手机软件里面收到服务器的数据