黑马程序员技术交流社区
标题: 【阳哥笔记】挑战年薪20W之Android笔记—Day04(网络编程) [打印本页]
作者: 阳哥忠粉 时间: 2015-6-27 23:48
标题: 【阳哥笔记】挑战年薪20W之Android笔记—Day04(网络编程)
~爱上海,爱黑马~
请求网络图片
网络交互就是基于HTTP协议请求和响应的过程。
XMPP协议用于即时通讯。
示例:
res\layout\activity_main.xml
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity" >
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="请求图片"
- android:onClick="click"/>
-
- <ImageView
- android:id="@+id/iv"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- />
- </RelativeLayout>
复制代码
src/cn.itcast.imageviewer/MainActivity.java
- package cn.itcast.imageviewer;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void click(View v){
- //向服务器发送Http请求去请求图片
- String path = "http://192.168.1.100:8080/sh.jpg";
- try{
- //1. 把网址封装成url对象
- URL url = new URL(path);
- //2. 打开一个连接对象
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- //3. 给连接对象做设置
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(8000);
- conn.setReadTimeout(8000);
- //4. 发送请求,建立连接
- conn.connect();
- //5. 获取响应码,如果为200开头,说明请求成功
- if(conn.getResponseCode() == 200){
- //获取服务器的流,服务器返回的数据是通过流写给客户端的,也就是说,流里就是请求的图片
- InputStream is = conn.getInputStream();
- //读取流里的数据,把数据构造成一个图片对象
- Bitmap bm = BitmapFactory.decodeStream(is);
- //把图片显示至屏幕
- ImageView iv = (ImageView) findViewById(R.id.iv);
- iv.setImageBitmap(bm);
- }else{
- Toast.makeText(this, "请求失败啦啦啦", 0).show();
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
复制代码
添加权限:
在Tomcat服务器webapps\ROOT存放图片:
运行结果:
双击start.bat,启动tomcat。
启动2.3.3版本模拟器,图片显示成功:
如果上面的示例运行在4.3版本的模拟器上,就会报警告:
在Android中,主线程是绝对不能阻塞的。因为,网络请求是耗时操作,主线程处于阻塞状态,用户任何操作都无效,处于类似于死机的状态。此时,点击HOME键有效,点击返回键、菜单键都没有反应。因为,返回键和菜单键是由当前应用程序自行处理,HOME键是由系统处理。应用程序可以阻塞自己的主线程,不可能阻塞Android系统。
为了保证用户体验良好,所有的耗时操作都不要写在主线程里,包括:请求网络、加载数据(数据库)和资源。
ANR:Application Not Responding,应用长时间不能响应用户操作。
查看出现ANR的原因,导出data/anr/traces.txt文件,打开。
ANR无法调试,解决方法就是在主线程中不要做耗时操作。
只有主线程可以刷新UI,主线程又称UI线程。这样做,是为了线程安全,只有一个线程可以刷新UI,如果有多个线程同时刷新UI,就可能出现线程安全导致UI刷新混乱的问题。
如果我们在MainActivity.java中启动一个线程进行网络请求,再次执行该应用程序就会报警告,如下:
通过异常可以看出来,刷新UI的代码必须在主线程中执行,但是请求图片的代码又由于不能引起阻塞,只能在子线程中执行,而且只有请求完图片之后才能刷新UI,这时候就形成了矛盾。Android里面提供了一种机制能够解决这个问题,也就是Handler机制。
Handler机制
主线程创建的时候,主线程中有一个消息队列MessageQueue,用来存放消息。还有一个Looper用来不断检测MessageQueue是否有消息。如果有消息就交给消息处理器Handler,Handler中有一个方法handleMessage,用来处理消息,这个方法是在主线程调用。那么,这个方法就可以刷新UI。如此,子线程想要刷新UI,只需调用Handler的sendMessag方法,将消息发送到MessageQueue即可。
示例:
src/cn.itcast.imageviewer2/MainActivity.java
- package cn.itcast.imageviewer2;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- Handler handler = new Handler(){
- //程序员需要重写handlerMessage方法,刷新UI
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what){
- case 1:
- //判断消息是成功消息还是失败消息
- ImageView iv = (ImageView) findViewById(R.id.iv);
- iv.setImageBitmap((Bitmap)msg.obj);
- break;
- case 2:
- Toast.makeText(MainActivity.this, "请求失败啦啦啦", 0).show();
- break;
- }
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void click(View v){
- Thread t = new Thread(){
- public void run(){
- String path = "http://192.168.1.100:8080/sh.jpg";
- try{
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(8000);
- conn.setReadTimeout(8000);
- conn.connect();
- if(conn.getResponseCode() == 200){
- InputStream is = conn.getInputStream();
- Bitmap bm = BitmapFactory.decodeStream(is);
- //创建消息对象
- Message msg = new Message();
- //消息对象可以携带数据
- msg.obj = bm;
- msg.what = 1;
- //发送消息至主线程的消息队列
- handler.sendMessage(msg);
- }else{
- Message msg = new Message();
- msg.what = 2;
- handler.sendMessage(msg);
- //由于Message没有携带任何数据,所以上面3句可以用下面1句替换。
- //handler.sendEmptyMessage(2);
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- };
- t.start();
- }
- }
复制代码 运行结果:
添加缓存功能的图片查看器
为了提升效率,查看图片后,缓存起来,便于下次查看图片不必在通过网络请求。
代码:
src/cn.itcast.imageviewer3/MainActivity.java
运行结果:
第一次,从网络获取。第二次再次点击按钮,从缓存获取。
获取开源代码
在程序开发中,会遇到很多问题。例如,请求图片过程中遇到断网,网速慢,图片过大内存不够等等情况。由于这些情况大部分项目都会遇到,所以网上有很多写好的现成的模块。不要重新发明轮子,可以直接拿来用。
好的开源网站:
搜索,下载源码,解压,复制到我们自己的应用程序项目中。
res\layout\activity_main.xml
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity" >
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="请求网络图片"
- android:onClick="click"
- />
- <com.loopj.android.image.SmartImageView
- android:id="@+id/iv"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_launcher"
- android:layout_centerInParent="true"
- />
- </RelativeLayout>
复制代码
SmartImageView是自定义控件,以后会有专门的课程讲解。
src/cn.itcast.smartimageview/MainActivity.java- package cn.itcast.smartimageview;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import com.loopj.android.image.SmartImageView;
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void click(View v){
- String path = "http://192.168.1.100:8080/sh.jpg";
-
- SmartImageView iv = (SmartImageView) findViewById(R.id.iv);
- iv.setImageUrl(path);
- }
- }
复制代码
添加权限:
运行结果:
Html源文件查看器
代码:
res\layout\activity_main.xml
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity" >
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="请求网络"
- android:onClick="click"/>
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <TextView
- android:id="@+id/tv"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- </ScrollView>
- </RelativeLayout>
复制代码
src/cn.itcast.htmlviewer.tool/Tools.java
- package cn.itcast.htmlviewer.tool;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- public class Tools {
- public static String getTextFromStream(InputStream is){
-
- try{
- byte[] b = new byte[1024];
- int len;
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- while((len = is.read(b)) != -1){
- bos.write(b,0,len);
- }
-
- //把输出流里的内容转换成字节数组
- String text = new String(bos.toByteArray());
- return text;
- }catch(IOException e){
- e.printStackTrace();
- }
-
- return null;
- }
- }
复制代码
src/cn.itcast.htmlviewer/MainActivity.java
- package cn.itcast.htmlviewer;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.widget.TextView;
- import cn.itcast.htmlviewer.tool.Tools;
- public class MainActivity extends Activity {
- Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- TextView tv = (TextView) findViewById(R.id.tv);
- tv.setText((String)msg.obj);
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void click(View v){
- Thread t = new Thread(){
- public void run(){
- String path = "http://192.168.1.100:8080/baidu.html";
- try{
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(8000);
- conn.setReadTimeout(8000);
-
- //先发送请求,再获取响应码,getResponseCode方法自身会发送请求消息
- if(conn.getResponseCode() == 200){
- InputStream is = conn.getInputStream();
- String text = Tools.getTextFromStream(is);
-
- //如果消息池中没有消息,new一个,如果有,复用这条空闲消息
- Message msg = handler.obtainMessage();
- msg.obj = text;
- handler.sendMessage(msg);
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- };
- t.start();
- }
- }
复制代码
添加权限:
运行结果:
那么Tools.java中代码只要进行如下修改即可:
新闻客户端布局
res\layout\item_listview.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
-
- <ImageView
- android:id="@+id/iv"
- android:layout_width="90dp"
- android:layout_height="70dp"
- android:src="@drawable/ic_launcher"
- android:layout_centerVertical="true"
- />
-
- <!-- android:singleLine是为了让过长的标题不会导致换行,影响美观 -->
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="22sp"
- android:text="这是标题"
- android:singleLine="true"
- android:layout_toRightOf="@+id/iv"
- />
-
- <!-- android:lines表示如果文本过长,最多显示几行 -->
- <TextView
- android:id="@+id/tv_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="15sp"
- android:text="这是详细"
- android:lines="2"
- android:textColor="@android:color/darker_gray"
- android:layout_toRightOf="@+id/iv"
- android:layout_below="@id/tv_title"
- />
-
- <TextView
- android:id="@+id/tv_comment"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="12345条评论"
- android:textColor="#ff0000"
- android:layout_alignParentRight="true"
- android:layout_below="@id/tv_detail"
- />
-
- </RelativeLayout>
复制代码 效果:
获取新闻信息
将news.xml和images文件夹存放在Tomcat服务器中。
News.xml- <?xml version="1.0" encoding="UTF-8" ?>
- <newslist>
- <news>
- <title>西安一期就业快报</title>
- <detail>热烈祝贺西安一期平均薪水突破13k</detail>
- <comment>15687</comment>
- <image>http://192.168.1.100:8080/images/6.jpg</image>
- </news>
- <news>
- <title>程序员因写代码太乱被杀害</title>
- <detail>凶手是死者同事,维护死者代码时完全看不懂而痛下杀手</detail>
- <comment>16359</comment>
- <image>http://192.168.1.100:8080/images/7.jpg</image>
- </news>
- <news>
- <title>产品经理因频繁改需求被杀害</title>
- <detail>凶手是一名程序员,因死者对项目需求频繁改动而痛下杀手</detail>
- <comment>14112</comment>
- <image>http://192.168.1.100:8080/images/7.jpg</image>
- </news>
- <news>
- <title>3Q大战宣判: 腾讯获赔500万</title>
- <detail>最高法驳回360上诉, 维持一审宣判.</detail>
- <comment>6427</comment>
- <image>http://192.168.1.100:8080/images/1.jpg</image>
- </news>
- <news>
- <title>今日之声:北大雕塑被戴口罩</title>
- <detail>市民: 因雾霾起诉环保局; 公务员谈"紧日子": 坚决不出去.</detail>
- <comment>681</comment>
- <image>http://192.168.1.100:8080/images/2.jpg</image>
- </news>
- <news>
- <title>奥巴马见达赖是装蒜</title>
- <detail>外文局: 国际民众认可中国大国地位;法院: "流量清零"未侵权.</detail>
- <comment>1359</comment>
- <image>http://192.168.1.100:8080/images/3.jpg</image>
- </news>
- <news>
- <title>轻松一刻: 我要沉迷学习不自拔</title>
- <detail>放假时我醒了不代表我起床了, 如今我起床了不代表我醒了!</detail>
- <comment>11616</comment>
- <image>http://192.168.1.100:8080/images/4.jpg</image>
- </news>
- <news>
- <title>男女那些事儿</title>
- <detail>"妈, 我在东莞被抓, 要2万保释金, 快汇钱到xxx!"</detail>
- <comment>10339</comment>
- <image>http://192.168.1.100:8080/images/5.jpg</image>
- </news>
- <news>
- <title>赵帅哥语录一</title>
- <detail>少壮不努力,老大做IT</detail>
- <comment>14612</comment>
- <image>http://192.168.1.100:8080/images/8.jpg</image>
- </news>
- <news>
- <title>赵帅哥语录二</title>
- <detail>问君能有几多愁,恰似调完代码改需求</detail>
- <comment>13230</comment>
- <image>http://192.168.1.100:8080/images/8.jpg</image>
- </news>
- <news>
- <title>赵帅哥语录三</title>
- <detail>觉得我帅的人工资一般都比较高</detail>
- <comment>9928</comment>
- <image>http://192.168.1.100:8080/images/8.jpg</image>
- </news>
- <news>
- <title>今日之声:北大雕塑被戴口罩</title>
- <detail>市民: 因雾霾起诉环保局; 公务员谈"紧日子": 坚决不出去.</detail>
- <comment>681</comment>
- <image>http://192.168.1.100:8080/images/2.jpg</image>
- </news>
- <news>
- <title>奥巴马见达赖是装蒜</title>
- <detail>外文局: 国际民众认可中国大国地位;法院: "流量清零"未侵权.</detail>
- <comment>1359</comment>
- <image>http://192.168.1.100:8080/images/3.jpg</image>
- </news>
- </newslist>
复制代码
src/cn.itcast.news.domain/News.java
- package cn.itcast.news.domain;
- public class News {
- private String title;
- private String detail;
- private String comment;
- private String imageUrl;
-
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- public String getDetail() {
- return detail;
- }
- public void setDetail(String detail) {
- this.detail = detail;
- }
- public String getComment() {
- return comment;
- }
- public void setComment(String comment) {
- this.comment = comment;
- }
- public String getImageUrl() {
- return imageUrl;
- }
- public void setImageUrl(String imageUrl) {
- this.imageUrl = imageUrl;
- }
- }
复制代码
src/cn.itcast.news/MainActivity.java
- package cn.itcast.news;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.List;
- import org.xmlpull.v1.XmlPullParser;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Xml;
- import cn.itcast.news.domain.News;
- public class MainActivity extends Activity {
- List<News> newsList;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- getNewsInfo();
- }
-
- private void getNewsInfo(){
- Thread t = new Thread(){
- public void run(){
- String path = "http://192.168.1.100:8080/news.xml";
- try{
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(8000);
- conn.setReadTimeout(8000);
-
- if(conn.getResponseCode() == 200){
- //获取服务器返回的流,流里就是xml文件
- InputStream is = conn.getInputStream();
- parserNewsInfo(is);
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- };
- t.start();
- }
-
- private void parserNewsInfo(InputStream is){
- XmlPullParser xp = Xml.newPullParser();
- try{
- xp.setInput(is,"utf-8");
-
- int type = xp.getEventType();
-
- News news = null;
-
- while(type != XmlPullParser.END_DOCUMENT){
- switch(type){
- case XmlPullParser.START_TAG:
- if("newslist".equals(xp.getName())){
- newsList = new ArrayList<News>();
- }else if("news".equals(xp.getName())){
- news = new News();
- }else if("title".equals(xp.getName())){
- String title = xp.nextText();
- news.setTitle(title);
- }else if("detail".equals(xp.getName())){
- String detail = xp.nextText();
- news.setDetail(detail);
- }else if("comment".equals(xp.getName())){
- String comment = xp.nextText();
- news.setComment(comment);
- }else if("image".equals(xp.getName())){
- String image = xp.nextText();
- news.setImageUrl(image);
- }
- break;
- case XmlPullParser.END_TAG:
- if("news".equals(xp.getName())){
- newsList.add(news);
- }
- break;
- }
- type = xp.next();
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
复制代码
把新闻信息显示至界面
修改res\layout\item_listview.xml中的ImageView标签为SmartImageView标签,便于显示图片。
src/cn.itcast.news/MainActivity.java
添加权限:
运行结果:
使用get方式提交表单
使用MyEclipse,新建一个Servlet:Login.java,把该Web项目部署到Tomcat服务器上。
src/cn.itcast.login/Login.java
- package cn.itcast.login;
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class Login extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- String name = request.getParameter("name");
- String pass = request.getParameter("pass");
-
- ServletOutputStream os = response.getOutputStream();
- if("asd".equals(name)&&"123".equals(pass)){
- os.write("登陆成功".getBytes("utf-8"));
- }else{
- os.write("登陆失败".getBytes("utf-8"));
- }
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
- }
复制代码
WebRoot/index.jsp
- <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- </head>
-
- <body>
- <form action="/Web/servlet/Login" method=get>
- 账号:<input type="text" name="name"><br/>
- 密码:<input type="text" name="pass"><br/>
- <input type="submit" value="登陆"/>
- </form>
- </body>
- </html>
复制代码
打开浏览器,输入地址,然后输入用户名和密码,提交。
Android之Get方式提交数据:
res\layout\activity_main.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity"
- android:orientation="vertical">
- <EditText
- android:id="@+id/et_name"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- <EditText
- android:id="@+id/et_pass"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="登陆"
- android:onClick="click"
- />
- </LinearLayout>
复制代码
src/cn.itcast.getmethod.tool/Tools.java
- package cn.itcast.getmethod.tool;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- public class Tools {
- public static String getTextFromStream(InputStream is){
-
- try{
- byte[] b = new byte[1024];
- int len;
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- while((len = is.read(b)) != -1){
- bos.write(b,0,len);
- }
-
- //把输出流里的内容转换成字节数组
- String text = new String(bos.toByteArray());
- return text;
- }catch(IOException e){
- e.printStackTrace();
- }
-
- return null;
- }
- }
复制代码
src/cn.itcast.getmethod/MainActivity.java - package cn.itcast.getmethod;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.widget.EditText;
- import android.widget.Toast;
- import cn.itcast.getmethod.tool.Tools;
- public class MainActivity extends Activity {
- Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- Toast.makeText(MainActivity.this, (String)msg.obj, 0).show();
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
-
- public void click(View v){
- EditText et_name = (EditText)findViewById(R.id.et_name);
- EditText et_pass = (EditText)findViewById(R.id.et_pass);
-
- String name = et_name.getText().toString();
- String pass = et_pass.getText().toString();
-
- //在url后面拼接要提交的数据
- final String path = "http://localhost:8080/Web/servlet/Login?name=" + name + "&pass=" + pass;
-
- Thread t = new Thread(){
- public void run(){
- URL url;
- try {
- url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(8000);
- conn.setReadTimeout(8000);
-
- if(conn.getResponseCode() == 200){
- InputStream is = conn.getInputStream();
- String text = Tools.getTextFromStream(is);
-
- Message msg = handler.obtainMessage();
- msg.obj = text;
- handler.sendMessage(msg);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- };
- t.start();
- }
- }
复制代码
添加权限:
运行结果:
提交表单的乱码问题
将Login.java中“zhangsan”修改为“张三”,并且打印出接收到的用户名及密码。
src/cn.itcast.login/Login.java
- package cn.itcast.login;
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class Login extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- String name = request.getParameter("name");
- String pass = request.getParameter("pass");
-
- System.out.println(name);
- System.out.println(pass);
-
- ServletOutputStream os = response.getOutputStream();
- if("张三".equals(name)&&"123".equals(pass)){
- os.write("登陆成功".getBytes("utf-8"));
- }else{
- os.write("登陆失败".getBytes("utf-8"));
- }
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
- }
复制代码 重新部署,运行。结果如下:
将浏览器编码调整为UTF-8。
可以看到,打印出来的为乱码。原因在于浏览器提交表单的时候,会把“张三”用UTF-8编码变成字节数组,然后传给服务器。服务器拿到这些字节以后,因为getParameter默认使用iso8859-1编码把读取到的字节数组构造成字符串,导致乱码。因此,解决方案为,首先使用iso8859-1把字符串重新转换成字节数组,然后再用utf-8构造成字符串即可。
重新部署,运行,结果如下:
尝试通过手机端发送中文的情况,如下:
输入中文,首先选择谷歌拼音输入法。
由上面的图片可以看到,依然存在乱码问题。原因在于浏览器提交的数据都是经过URL编码的,所以,通过代码提交的数据就需要手动编码。
修改后,运行结果:
使用post方式提交表单
修改表单为post提交方式:
通过代码实现post提交请求,一方面通过流的方式将数据传输给服务器,一方面是给post请求头添加额外属性。
src/cn.itcast.postmethod/MainActivity.java
- package cn.itcast.postmethod;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.net.URLEncoder;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.widget.EditText;
- import android.widget.Toast;
- import cn.itcast.getmethod.tool.Tools;
- public class MainActivity extends Activity {
- Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- Toast.makeText(MainActivity.this, (String)msg.obj, 0).show();
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
-
- public void click(View v){
- EditText et_name = (EditText)findViewById(R.id.et_name);
- EditText et_pass = (EditText)findViewById(R.id.et_pass);
-
- final String name = et_name.getText().toString();
- final String pass = et_pass.getText().toString();
-
- final String path = "http://192.168.1.100:8080/Web/servlet/Login";
-
- Thread t = new Thread(){
-
- public void run(){
- URL url;
- try {
- url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("POST");
- conn.setConnectTimeout(8000);
- conn.setReadTimeout(8000);
-
- //post请求头需要添加额外属性
- conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
-
- String content = "name=" + URLEncoder.encode(name) + "&pass=" + pass;
- conn.setRequestProperty("Content-Length", content.length() + "");
-
- //开启请求头的流,把要提交的数据写入流中
- //设置打开连接对象输出流
- conn.setDoOutput(true);
- OutputStream os = conn.getOutputStream();
-
- os.write(content.getBytes());
-
- if(conn.getResponseCode() == 200){
- InputStream is = conn.getInputStream();
- String text = Tools.getTextFromStream(is);
-
- Message msg = handler.obtainMessage();
- msg.obj = text;
- handler.sendMessage(msg);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- };
- t.start();
- }
- }
复制代码 运行结果:
~END~
作者: jwl245322883 时间: 2015-6-28 00:32
在论坛这么久,第一次抢到首席
作者: 遮天 时间: 2015-6-28 10:11
一直关注中............
作者: 黑马94那么拽 时间: 2015-6-28 10:42
先收藏了。。。。。
作者: keto 时间: 2015-6-28 16:04
慢慢学习。。。。。
作者: HM_HC 时间: 2015-6-28 16:21
慢慢学习
作者: javazhang 时间: 2015-6-28 17:36
每天总有收货就是最大的进步!
作者: tinibuzhi 时间: 2015-6-28 22:28
学习了:victory:
作者: qian0217wei 时间: 2015-6-28 23:32
支持阳哥!
作者: zhangcong 时间: 2015-6-29 12:27
阳哥的笔记真赞,后面得认真看看!
作者: javazhang 时间: 2015-7-1 10:45
不管刮风还是下雨打炸雷,我都会到帖子里看一看。
作者: ZhangHeng 时间: 2015-7-1 13:05
今天一小步,明天一大步。
作者: 黑马:二师兄 时间: 2015-7-7 18:04
小赞怡情,大赞伤身!
作者: 星痕-凌 时间: 2015-7-9 22:27
顶 顶 顶 顶 !!!!!!!!!!!!!!!!!!!!
作者: RichardM 时间: 2015-7-9 23:16
阳哥笔记,好资料呀,值得好好学习学习
作者: RichardM 时间: 2015-7-9 23:20
厉害呀,必须得好好学习一番。。。。
作者: 雪域雄鹰 时间: 2016-2-25 20:11
宝贵的资源,要好好学习!
作者: 雪域雄鹰 时间: 2016-2-27 13:56
好好学习!
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |