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>