ByteArrayOutputStream此类实现了一个输出流,
其中的数据被写入一个 byte 数组。
缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
它最大的作用就是缓冲。其实是把数据先写到内存里面了。其实是把流转换成byte数组
并且写到内存中。
/**
* 把一个inputstream里面的内容转化成一个byte[]
* @throws IOException
*/
public static byte[] getBytes(InputStream inputStream) throws IOException{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = inputStream.read(buffer))!=-1){
bos.write(buffer, 0, len);//其实是写到 了内存中。
}
inputStream.close();
bos.close();
byte[] resutl = bos.toByteArray();//如果你这这样写,内存会一直增加。
System.out.println(new String(resutl));
return resutl;
}
安卓上默认的是UTF-8.
初始化布局填充器的两种方法。。
你的资源性文件不能与JAVA中关键字重名,因为所有的资源性文件最终都会以R文件的内部类的形式作
为一个命名,如果你用了JAVA关键字,在这里生成相应的引用的时间会造成错误。这点切记 。
从今天开始,你必须要明白为什么人们把各种流转换成字节流,因为底层就是字节流,八位一个字节,
read()每次就是读取一个字节,也就是说JAVA读取的最基本单位都是字节,所以要把流转换成字节数组。
URL url = new URL(path);
url.openConnection();//这个方法返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。
//每次调用此 URL 的协议处理程序的 openConnection 方法都打开一个新的连接。
//也就是说,每次调用一次这个方法就访问一次path这个路径。那么从这个地址返回的数据流用
conn.getInputStream();接收。把流接收之后转换成字节数组流,其实就是一大群有序的字节,
然后new String(bytes);然后我们就得到了从流里面返回的字串,多么有逻辑的一个过程呀。
//知识点
android:layout_gravity是用来设置该view相对与起父view 的位置.
比如一个button 在linearlayout里,你想把该button放在靠左、靠右等位置就可以通过该属性设置.
以button为例,android:layout_gravity="right"则button靠右
//透析 GET提交 方式 。
1、首先在客户端,你想要发中文,还是以GET方式发的,只有一种可能,你必须要它进行URLEncoder,
//该类包含了将 String 转换为 application/x-www-form-urlencoded MIME 格式的静态方法只有这样才能够正常的发出去。
2、你能够正常发了,记住,所有的数据都必须要以0011的方式才能够提交,但是,你到了tomcat那里,tomcat默认的编码集
//是iso8859-1,它会以这种编码集对这些0011进行解码(详细的在下面),所以中文服务器要想正确的收也要设置,先让这些东西
//转化成iso8859-1的字节数组,然后再对其用UTF-8编码不就行了。(再次加深理解了为什么一切都要转化为字节数组,因为JAVA
//读 写数据最基本的单位是一个字节)
客户端:
String u = URLEncoder.encode(username);
String p = URLEncoder.encode(password);
服务器:
String name = request.getParameter("username");
String password = request.getParameter("password");
name = new String(name.getBytes("iso8859-1"), "utf-8");
password = new String(password.getBytes("iso8859-1"), "utf-8");
至此,你已经了解了GET方式的精华。
//URLEncoder:详解。
对 String 编码时,使用以下规则:
字母数字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。
特殊字符 "."、"-"、"*" 和 "_" 保持不变。
空格字符 " " 转换为一个加号 "+"。
所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。
然后每个字节用一个包含 3 个字符的字符串 "%xy" 表示,其中 xy 为该字节的两位十六进制表示形式。
推荐的编码机制是 UTF-8。但是,出于兼容性考虑,如果未指定一种编码,则使用相应平台的默认编码。
例如,使用 UTF-8 编码机制,字符串 "The string ü@foo-bar" 将转换为 "The+string+%C3%BC%40foo-bar",
因为在 UTF-8 中,字符 ü 编码为两个字节,C3 (十六进制)和 BC (十六进制),字符 @ 编码为一个字节 40 (十六进制)。
一个汉字按照UTF-8URL 之后会有三个,下面是中国的编码。
http://zh.wikipedia.org/zh/%E4%B8%AD%E5%9C%8B
http://www.baidu.com/s?wd=%E4%B8%AD%E5%9B%BD
属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母a的编码为0x61=97。
//iso8859-1详解。
很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。
但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,
仍旧使用iso8859-1编码来表示。而且在很多协议上,默认使用该编码。比如,
虽然"中文"两个字不存在iso8859-1编码,以gb2312编码为例,应该是"d6d0 cec4"两个字符,
使用iso8859-1编码的时候则将它拆开为4个字节来表示:"d6 d0 ce c4"(事实上,在进行存储的时候,也是以字节为单位处理的)。
//GEt POST的区别?
get一次提交数据量小,只能提交4K。内部其实是通过拼URL的方式。
POST不限制,且是以form表单的形式流提交给服务器的。
FUCK POST方式竟然也这么复杂。
服务器端:(POST与GET一样。)
String name = request.getParameter("username");
String password = request.getParameter("password");
response.getWriter().print(name + password + " ==");
if (name != null) {
name = new String(name.getBytes("iso8859-1"), "utf-8");
}
if (password != null) {
password = new String(password.getBytes("iso8859-1"), "utf-8");
}
System.out.println(name +"username");
System.out.println(password +"password");
response.setCharacterEncoding("utf-8");//这里这样设置,因为安卓默认是UTF-8编码,所以就这样了。
response.getWriter().print("登陆成功");
客户端:
/**
* 采用post的方式 提交数据到服务器
*
* @param path
* 服务器servlet的地址
* @param name
* 用户名
* @param password
* 密码
* @return 服务器返回的数据信息
* @throws IOException
* @throws Exception
*/
public static String sendDataByPost(String path,String username,String password) throws IOException{
String u = URLEncoder.encode(username);
String p = URLEncoder.encode(password);
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//发送的数据还要自己拼接,并且也要先转码application/x-www-form-urlencoded
String data = "username=" + u + "&password=" + p;
connection.setRequestMethod("POST");
//将此 URLConnection 的 doOutput 字段的值设置为指定的值。
connection.setDoOutput(true);
connection.setDoInput(true);
// 设置http协议的消息头 POST提交 方式 中两个 HTTP协议头必不可少
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", data.length() + "");
// 把我们准备好的data数据写给服务器 因为post是以流的方式 写的。
OutputStream os = connection.getOutputStream();
os.write(data.getBytes());
int code = connection.getResponseCode();
if (code == 200) {
InputStream inputStream = connection.getInputStream();
byte[] bytes = StreamUtil.getBytes(inputStream);
return new String(bytes);
}else {
throw new IllegalStateException("服务器状态异常");
}
}
Activity:
String u1 = username.getText().toString().trim();
String p1 = password.getText().toString().trim();
if (u1 == "" || p1 == "") {
Toast.makeText(LoginActivity.this, "用户名或密码不能为空", Toast.LENGTH_LONG).show();
return ;
}
//获取要访问的路径
String path1 = getResources().getString(R.string.serverurl);
System.out.println(u1+p1+path1+" ---");
try {
String resString = DataService.sendDataByPost(path1, u1, p1);
Toast.makeText(LoginActivity.this, resString, 0).show();
} catch (IOException e) {
e.printStackTrace();
}
//以上是面向HTTP协议编程,用起来十分麻烦,而且容易引起问题。所以出现了HTTPClient.
httpclient 浏览器的简单包装
new HttpClient 就相当于得到了一个浏览器
具体参看代码。
//上传。
首先,你要会WEB的上传,WEB上传很简单,加入两个JAR包,然后在Servlet里面写上相应的代码,在JSP
里面写上一个file类型的。
<form action="/web/DemoServlet" method="post" enctype="multipart/form-data">
姓名<input name="name" value="" >
密码<input name="password" value="">
文件<input name="file" type="file">
提交<input type="submit" value="进入"/>
</form>
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
String realpath = request.getSession().getServletContext().getRealPath("/files");
System.out.println(realpath);
File dir = new File(realpath);
if(!dir.exists()) dir.mkdirs();
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
try {
List<FileItem> items = upload.parseRequest(request);
for(FileItem item : items){
if(item.isFormField()){
String name1 = item.getFieldName();//得到请求参数的名称
String value = item.getString("UTF-8");//得到参数值
System.out.println(name1+ "="+ value);
}else{
item.write(new File(dir, System.currentTimeMillis()+ item.getName().substring(item.getName().lastIndexOf("."))));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}else{
doGet(request, response);
}
然后就这样你就上传成功了。!!!!
开始移植安卓。
1,首先把安卓没有集成的HttpClientjar包给集成进去 。
2,写一个服务的方法,去发送并且接收数据。
3,在Activity中调用这个服务的方法。
/**
* 提交数据给服务器 带一个文件
* @param path
* @param name
* @param password
* @param filepath 文件在手机上的路径
* @return
* @throws Exception
*/
public static String sendDataByHttpClientPost(String path , String name,String password ,String filepath) throws Exception{
// 实例化上传数据的 数组 part []
Part[] parts = {new StringPart("name", name),
new StringPart("password", password),
new FilePart("file", new File(filepath))};
PostMethod filePost = new PostMethod(path);
filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
client.getHttpConnectionManager().getParams()
.setConnectionTimeout(5000);
int status = client.executeMethod(filePost);
if(status==200){
// String result = filePost.getResponseBodyAsString();
// System.out.println( filePost.getResponseCharSet());
String result = new String(filePost.getResponseBodyAsString());
String ha = new String ( result.getBytes("ISO-8859-1"),"UTF-8");
System.out.println(ha);
System.out.println("--"+ha);
return ha;
}
else{
throw new IllegalStateException("服务器状态异常");
}
}
case R.id.fileupload:
String filePathString = filePath.getText().toString().trim();
if ("".equals(filePathString)) {
Toast.makeText(this, "路径不能为空", 0).show();
return ;
}
try {
String result = DataService.sendDataByHttpClientPost(getResources().getString(R.string.serverurl)
,username.getText().toString().trim() ,
password.getText().toString().trim(),
filePathString);
System.err.println(result +"hahahhaha");
Toast.makeText(this, result, 0).show();
System.out.println(new String( result.getBytes("iso8859-1"),"utf-8"));
} catch (NotFoundException e) {
Toast.makeText(this, "访问网路异常", 0).show();
e.printStackTrace();
} catch (Exception e) {
Toast.makeText(this, "访问网路异常", 0).show();
e.printStackTrace();
}
break;
这个东西有可能会出现乱码,自己要想好是在哪一层出错的。
并且理解tomcat服务器的编码方式。还有安卓自己的编码方式。
//webservice可以理解为任何提供数据的服务器。
例如我的手机想要调用WEB服务器里面某个类里面的
某个方法。就要用到soap肥皂协议
simple object access protocol
其实我们就是给这个网站提交我们的访问信息,然后它返回一个信息。
我们提交的是它想要的XML,得到的也是一个XML,再解析就是了。
核心代码。
package cn.itcast.service;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.R.integer;
import android.util.Xml;
public class QueryService {
public static String getAddress(String number) throws Exception{
InputStream inputStream = QueryService.class.getClassLoader().getResourceAsStream("data.xml");
byte[] bytes = StreamTool.getBytes(inputStream);
String xml = new String(bytes);
String postxml = xml.replace("$mobile", number);
System.out.println(postxml);
//其实就是把这个有我们输入号码的XML传给服务器,服务器会返回相应的值 。
String res = sendDataByPost(postxml);
System.out.println(res +" 结果。");
return res;
}
/**
* 采用post的方式 提交数据到服务器
*
* @param path
* 服务器servlet的地址
* @param name
* 用户名
* @param password
* 密码
* @return 服务器返回的数据信息
* @throws Exception
* @throws Exception
*/
public static String sendDataByPost(String postxml) throws Exception{
String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//发送的数据还要自己拼接,并且也要先转码application/x-www-form-urlencoded
String data = postxml;
connection.setRequestMethod("POST");
//将此 URLConnection 的 doOutput 字段的值设置为指定的值。
connection.setDoOutput(true);
connection.setDoInput(true);
// 设置http协议的消息头 POST提交 方式 中两个 HTTP协议头必不可少
connection.setRequestProperty("Content-Type",
"application/soap+xml;charset=utf-8");
connection.setRequestProperty("Content-Length", data.length() + "");
// 把我们准备好的data数据写给服务器 因为post是以流的方式 写的。
OutputStream os = connection.getOutputStream();
os.write(data.getBytes());
int code = connection.getResponseCode();
if (code == 200) {
//其实这个流就是下面的数据, 我们解析这个XML即可得到想要的结果 。
//<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"><getMobileCodeInfoResult>15136225969:河南 郑州 河南移动全球通卡</getMobileCodeInfoResult></getMobileCodeInfoResponse></soap:Body></soap:Envelope> 结果。
InputStream inputStream = connection.getInputStream();
String address = parseXml(inputStream);
return new String(address);
}else {
throw new IllegalStateException("服务器状态异常");
}
}
public static String parseXml(InputStream inputStream) throws XmlPullParserException, IOException{
XmlPullParser parser = Xml.newPullParser();
parser.setInput(inputStream, "utf-8");
int type = parser.getEventType();
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if ("getMobileCodeInfoResult".equals(parser.getName())) {
return parser.nextText();
}
break;
}
type = parser.next();
}
return "没有找到";
}
}
data.xml
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getMobileCodeInfo xmlns="http://WebXml.com.cn/">
<mobileCode>$mobile</mobileCode>
<userID></userID>
</getMobileCodeInfo>
</soap12:Body>
</soap12:Envelope>
安卓学习第四天
最新推荐文章于 2024-03-09 23:50:11 发布