1.通过调用URL对象openConnection()方法来创建URLConnection对象
2.设置URLConnection的参数和普通的请求属性
3.如果只是发送GET方式请求,使用connet方法建立和远程资源之间的实际连接即可;如果发送POST方式的请求,需要获取URLConnection实例对应的输出流来发送请求参数。
4.远程资源变为可用,程序可以访问远程资的头字段,或通过输入流读取远程资源的数据。
需求:示范如何向Web站点发送GET请求、POST请求,并从Web站点取的响应。
模拟用户登录的Serlvet
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("姓名="+username);
System.out.println("密码="+password);
if("lisi".equals(username) && "123".equals(password)){
response.getOutputStream().write("success".getBytes());
}else{
response.getOutputStream().write("failed".getBytes());
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
在地址栏中输入:
http://localhost:8080/ServerDemo1/servlet/LoginServlet?username=lisi&password=123
页面返回:
页面返回登录成功的信息:success.查看该页面的源文件也只是个:success
需求:从客户端请求数据到服务端,将服务端的信息返回个服务端。
工具类:
NetUtil.java
public class NetUtil {
private static final String TAG = "NetUtil";
/**
* 使用GET的方式登录
* @param username
* @param password
* @return 登录的状态
*/
public static String loginOfGet(String username,String password){
HttpURLConnection conn = null;
try {
String data = "username="+username+"&password="+password;
URL url = new URL("http://10.3.5.154:8080/ServerDemo1/servlet/LoginServlet?"+data);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");//GET和POST必须全大写
conn.setConnectTimeout(10000);//连接的超时时间
conn.setReadTimeout(5000);//读数据的超时时间
int responseCode = conn.getResponseCode();
if(responseCode==200){
//访问成功,通过流取的页面的数据信息
InputStream is = conn.getInputStream();
String status = getStringFromInputStream(is);
return status;
}else{
Log.i(TAG, "访问失败:"+responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if(conn!=null){
conn.disconnect();//释放链接
}
}
return null;
}
/**
* 使用POST提交方式
* @param username
* @param password
* @return
*/
public static String loginOfPost(String username, String password) {
HttpURLConnection conn = null;
try {
URL url = new URL("http://10.3.5.154:8080/ServerDemo1/servlet/LoginServlet");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");//GET和POST必须全大写
conn.setConnectTimeout(10000);//连接的超时时间
conn.setReadTimeout(5000);//读数据的超时时间
conn.setDoOutput(true);//必须设置此方法 允许输出
// conn.setRequestProperty("Content-Length", 234);//设置请求消息头 可以设置多个
//post请求的参数
String data = "username="+username+"&password="+password;
OutputStream out = conn.getOutputStream();
out.write(data.getBytes());
out.flush();
out.close();
int responseCode = conn.getResponseCode();
if(responseCode==200){
//访问成功,通过流取的页面的数据信息
InputStream is = conn.getInputStream();
String status = getStringFromInputStream(is);
return status;
}else{
Log.i(TAG, "访问失败:"+responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if(conn!=null){
conn.disconnect();//释放链接
}
}
return null;
}
/**
* 通过字节输入流返回一个字符串信息
* @param is
* @return
* @throws IOException
*/
private static String getStringFromInputStream(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len=0;
while((len=is.read(buffer))!=-1){
baos.write(buffer, 0, len);
}
is.close();
String status = baos.toString();// 把流中的数据转换成字符串, 采用的编码是: utf-8
baos.close();
return status;
}
}
Java代码:
MainActivity.java
public class MainActivity extends Activity {
private EditText et_username;
private EditText et_password;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_username = (EditText) findViewById(R.id.et_username);
et_password = (EditText) findViewById(R.id.et_password);
}
//GET提交方式
public void doGet(View view){
final String username = et_username.getText().toString().trim();
final String password = et_password.getText().toString().trim();
new Thread(new Runnable() {
@Override
public void run() {
//使用GET方式抓取数据
final String status = NetUtil.loginOfGet(username, password);
//执行任务在主线程中
runOnUiThread(new Runnable() {
@Override
public void run() {
//就是在主线程中操作
Toast.makeText(MainActivity.this, status, 0).show();
}
});
}
}).start();
}
//POST提交方式
public void doPost(View view){
final String username = et_username.getText().toString().trim();
final String password = et_password.getText().toString().trim();
new Thread(new Runnable() {
@Override
public void run() {
final String status = NetUtil.loginOfPost(username,password);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, status, 0).show();
}
});
}
}).start();
}
}
运行效果图:
采用get或者post提交方式
从客户端提交数据到服务器端,将服务器端的信息,返回给了客户端。
但是以上代码存在严重的中文乱码问题:
乱码简单分析:
明白了产生乱码的原因,这时候我们分析解决乱码的步骤:
(把握住:保证客户端与服务器端采用的编码必须一致)
修改NetUtil.java
截图:
修改的代码:
/**
* URLEncoder.encode(String s, String charsetName)对url中的中文参数进行编码,可以解决乱码
*/
String data = "username="+URLEncoder.encode(username, "utf-8")+"&password="+URLEncoder.encode(password, "utf-8");
URL url = new URL("http://10.3.5.154:8080/ServerDemo1/servlet/LoginServlet?"+data);
conn = (HttpURLConnection) url.openConnection();
修改LoginServlet.java
截图:
修改的代码:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");//请求过来的参数,是采用的编码是: iso8859-1
String password = request.getParameter("password");
//采用iso8859-1的编码对姓名进行逆转,转换成字节数组,再使用utf-8编码对数据进行转换,字符串
username = new String(username.getBytes("iso8859-1"), "utf-8");
password = new String(password.getBytes("iso8859-1"), "utf-8");
System.out.println("姓名="+username);
System.out.println("密码="+password);
if("lisi".equals(username) && "123".equals(password)){
response.getOutputStream().write("登录成功".getBytes("utf-8"));
}else{
response.getOutputStream().write("登录失败".getBytes("utf-8"));
}
}
服务器端:
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");//请求过来的参数,是采用的编码是: iso8859-1
String password = request.getParameter("password");
//采用iso8859-1的编码对姓名进行逆转,转换成字节数组,再使用utf-8编码对数据进行转换,字符串
username = new String(username.getBytes("iso8859-1"), "utf-8");
password = new String(password.getBytes("iso8859-1"), "utf-8");
System.out.println("姓名="+username);
System.out.println("密码="+password);
if("lisi".equals(username) && "123".equals(password)){
/**
* getBytes默认情况下,使用iso8859-1的编码,但如果发现码表中没有当前字符
* 会使用当前系统下的默认编码gbk;
*/
response.getOutputStream().write("登录成功".getBytes("utf-8"));
}else{
response.getOutputStream().write("登录失败".getBytes("utf-8"));
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
客户端代码:
工具类:
public class NetUtil {
private static final String TAG = "NetUtil";
/**
* 使用GET的方式登录
* @param username
* @param password
* @return 登录的状态
*/
public static String loginOfGet(String username,String password){
HttpURLConnection conn = null;
try {
/**
* URLEncoder.encode(String s, String charsetName)对url中的中文参数进行编码,可以解决乱码
*/
String data = "username="+URLEncoder.encode(username, "utf-8")+"&password="+URLEncoder.encode(password, "utf-8");
//get方式,url是直接在后面拼接地址的
URL url = new URL("http://10.3.5.154:8080/ServerDemo1/servlet/LoginServlet?"+data);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");//GET和POST必须全大写
conn.setConnectTimeout(10000);//连接的超时时间
conn.setReadTimeout(5000);//读数据的超时时间
int responseCode = conn.getResponseCode();
if(responseCode==200){
//访问成功,通过流取的页面的数据信息
InputStream is = conn.getInputStream();
String status = getStringFromInputStream(is);
return status;
}else{
Log.i(TAG, "访问失败:"+responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if(conn!=null){
conn.disconnect();//释放链接
}
}
return null;
}
/**
* 使用POST提交方式
* @param username
* @param password
* @return
*/
public static String loginOfPost(String username, String password) {
HttpURLConnection conn = null;
try {
//post请求的url地址是以流的方式写过去的
URL url = new URL("http://10.3.5.154:8080/ServerDemo1/servlet/LoginServlet");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");//GET和POST必须全大写
conn.setConnectTimeout(10000);//连接的超时时间
conn.setReadTimeout(5000);//读数据的超时时间
conn.setDoOutput(true);//必须设置此方法 允许输出
// conn.setRequestProperty("Content-Length", 234);//设置请求消息头 可以设置多个
//post请求的参数
String data = "username="+username+"&password="+password;
// 获得一个输出流, 用于向服务器写数据, 默认情况下, 系统不允许向服务器输出内容
OutputStream out = conn.getOutputStream();
out.write(data.getBytes());
out.flush();
out.close();
int responseCode = conn.getResponseCode();
if(responseCode==200){
//访问成功,通过流取的页面的数据信息
InputStream is = conn.getInputStream();
String status = getStringFromInputStream(is);
return status;
}else{
Log.i(TAG, "访问失败:"+responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if(conn!=null){
conn.disconnect();//释放链接
}
}
return null;
}
/**
* 通过字节输入流返回一个字符串信息
* @param is
* @return
* @throws IOException
*/
private static String getStringFromInputStream(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len=0;
while((len=is.read(buffer))!=-1){
baos.write(buffer, 0, len);
}
is.close();
String status = baos.toString();// 把流中的数据转换成字符串, 采用的编码是: utf-8
baos.close();
return status;
}
}
MainActivity.java类没有改变和上面的一样。