1? ? ? Servlet&網絡訪問
B/S的S? Server?http網絡應用服務端軟件
http?Hyper Text Transmission Protocol 超文本傳輸協(xié)議舆声,處于四層架構中的應用層棋傍,是建立TCP的基礎上
網絡應用服務端軟件可以看成一個容器铆铆,我們將網絡應用部署到其中并啟動豌汇,這個容器就可以按照我們的意愿去工作郎楼,處理客戶端的請求并響應
常用網絡應用服務端軟件:Tomcat爪喘、JBoss蹄咖、Websphere、WebLogic
如何寫Web項目:
1钳幅、HttpServlet 小的服務端組件 定義一個類繼承它
2物蝙、重寫其中的doGet、doPost方法,在這兩個方法里寫上如何處理客戶端的請求敢艰,這兩個方法是回調方法诬乞,doGet處理Get請求、doPost處理Post請求
3钠导、在web.xml中注冊這個類震嫉,告訴容器在處理某一類型請求的時候,使用這個類中的邏輯
可以使用HttpServletRequest的getParameter方法獲取請求中某參數(shù)的值
可以使用HttpServletResponse的getOutputStream方法獲取響應的輸出流牡属,給客戶端寫信息
C/S 中的 C
URL類? Uniform Resource Locator統(tǒng)一資源定位器
構造方法:URL(String url)把一個字符串形式的url構建出一個URL對象
openConnection() 獲取網絡連接URLConnection對象票堵,一般會將其強轉為HttpURLConnection類型,并作相應操作逮栅。(調用這個方法時這個連接并沒有真正產生)
HttpURLConnection 類
主要方法:
connect()?產生真正的連接
getInputStream() 獲取響應體輸入流悴势,可以用來接收服務端響應
getResponseCode()獲取響應狀態(tài)碼,200為正常措伐,這個方法必須在連接之后以及請求發(fā)出去之后才調用特纤,否則它會隱式調用connect()方法,出現(xiàn)一些奇怪的狀況
getOutputStream()獲取請求體的輸出流侥加,可以往請求體中寫
setRequestMethod()設置請求方式捧存,默認為GET,如果是POST方式就一定要使用這個方法
setDoOutput() 設置是否可以往連接中輸出担败,默認是false昔穴,如果是POST方式,一定要設為true
setDoInput() 設置是否可從連接中讀出提前,默認為true,所以這個方法不需要使用
GET請求:
把參數(shù)放在url里面吗货,和服務端連接,讀取服務端響應
1岖研、創(chuàng)建URL(后面跟著參數(shù) )
2卿操、獲取連接
3、產生連接
4孙援、判斷狀態(tài)碼害淤,是200就讀取響應內容
POST請求:
1、創(chuàng)建URL(后面沒參數(shù))
2拓售、獲取連接
3窥摄、設置請求方法setRequestMethod("POST")
設置允許輸出setDoOutput(true),允許往請求(體)里寫
4、產生連接
5础淤、獲取連接的輸出流崭放,往請求(體)中寫參數(shù)
6哨苛、讀取響應內容
【
C/S:Client/Server:《優(yōu)點:客戶端可以任意設計,可以展示絢麗的效果和特殊功能币砂;對于網速的依賴沒有B/S那么強
缺點:使用時需要下載客戶端并安裝建峭,所有客戶端都需要聯(lián)網更新》
B/S:Browser/Server:《優(yōu)點:不需要下載任何客戶端,只要有瀏覽器就可以使用决摧,當程序需要更新時亿蒸,只需要在服務端進行更新即可
缺點:所有的運算都要在服務端完成,服務器壓力和大掌桩,并且瀏覽器暫時不具備展示十分絢麗的效果的能力边锁;十分依賴網絡(網速)》
Http協(xié)議:《Hypertext Transfer Protocol:超文本傳輸協(xié)議,它是以TCP/IP為基礎的高層協(xié)議
定義瀏覽器和web服務器之間交換數(shù)據(jù)的過程以及數(shù)據(jù)格式
定義Web瀏覽器和web服務器之間通訊的協(xié)議
現(xiàn)在廣泛使用的版本是Http/1.1波岛。相對于Http/1.0來說茅坛,最大的特點就是支持持續(xù)連接(即一次TCP連接上可以包含多次請求和響應)
常見狀態(tài)碼:《消息(1字頭):100???? 成功(2字頭):200?? 重定向(3字頭)
請求錯誤(4字頭):404??? 服務器錯誤(5、6字頭):500》
》
】
【
Servlet是SUN公司提供的一種用于開發(fā)動態(tài)web資源的技術
Sun公司在其API中提供了一個Servlet接口则拷,根據(jù)該接口編寫的程序沒有main方法贡蓖。它們受控于另一個Java應用,這個Java應用稱為Servlet容器隔躲,Tomcat就是這樣一個容器
】
【
Inserttitle here
-->
action:服務器的地址
method:數(shù)據(jù)的提交方式,常用的有兩種:get摩梧、post
-->
用戶名:
密碼:
publicclass MyServlet extends HttpServlet {
// 序列值
private static final longserialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
*
* 用于處理來自客戶端的網絡請求(get方式)
* 參數(shù)1:request物延,來自客戶端的請求對象宣旱,封裝了客戶端向服務端發(fā)送的請求數(shù)據(jù)
* 參數(shù)2:response,通過該對象可以向客戶端做出響應
*/
protected void doGet(HttpServletRequestrequest, HttpServletResponse response) throws ServletException, IOException {
// 獲取賬號叛薯、密碼
response.setCharacterEncoding("GBK");
String name= request.getParameter("username");
String pwd= request.getParameter("pwd");
System.out.println(name+ "..." + pwd);
if("admin".equals(name)&& "123".equals(pwd)) {
//登陸成功
response.getWriter().print("loginsuccess...(登陸成功)");
} else {
//登陸失敗
response.getWriter().print("loginfailed...(登陸失敾胍鳌)");
}
}
/**
* 用于處理來自客戶端的網絡請求(post方式)
*/
protected voiddoPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {
// TODO Auto-generated methodstub
this.doGet(request,response);
}
}
】
基于JSP的實現(xiàn)形式:
【
<%@page language="java" import="java.util.*"pageEncoding="utf-8"%>
<%
Stringpath = request.getContextPath();
%>
測試HTTP協(xié)議體的內容
-->
-->
/servlet/LoginAction">
用戶名:
密? 碼:
publicclass LoginAction extends HttpServlet {
/**
* Constructor of the object.
*/
public LoginAction() {
super();
}
/**
* Destruction of the servlet.
*/
public void destroy() {
super.destroy(); // Just puts"destroy" string in log
// Put your code here
}
public void doGet(HttpServletRequestrequest, HttpServletResponse response)
throwsServletException, IOException {
this.doPost(request,response);
}
public void doPost(HttpServletRequestrequest, HttpServletResponse response)
throwsServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
PrintWriter out =response.getWriter();
String username =request.getParameter("username");
System.out.println("-username->>"+username);
String pswd =request.getParameter("password");
System.out.println("-password->>"+pswd);
if(username.equals("admin")&&pswd.equals("123")){
//表示服務器端返回的結果
out.print("loginis success!!!!");
}else{
out.print("loginis fail!!!");
}
out.flush();
out.close();
}
public void init() throwsServletException {
// Put your code here
}
}
】
【
什么是URL?:《URL(UniformResource Locator)是統(tǒng)一資源定位符的簡稱
表示Intent上某一資源的地址
通過URL可以訪問Intenet上的各種網絡資源耗溜,比如常見的www组力、FTP站點》
URL的基本結構由5部分組成:《<傳輸協(xié)議>://<主機名>:<端口號>/<文件名>#<引用>
http://www.tomcat.com:80/Gamelan/network.html#BOTTOM》
】
【
方式一:HttpUrlConnection類:《1、獲取網絡連接對象
1抖拴、 設置網絡數(shù)據(jù)請求的方式(默認GET)
2燎字、 設置連接超時的時間,如果超時阿宅,說明沒有連接成功候衍,就會拋出異常
3、 設置接收數(shù)據(jù)超時的時間洒放,如果超時蛉鹿,就會排除異常
4、 驗證服務器的返回碼
5往湿、 通過IO流傳輸數(shù)據(jù)
6妖异、 解析數(shù)據(jù)
PS:POST請求需要另外設置請求參數(shù)
Content-Type:application/x-www-form-urlencoded
Content-Length: 數(shù)據(jù)的大小
》
】
方式二:ApacheHttpClient框架:【
《HttpClient是由Apache開源組織提供的一個開源項目惋戏,它是一個簡單的Http客戶端(并不是瀏覽器),可以用于發(fā)送Http請求他膳,接收Http響應》
《簡單來說响逢,HttpClient就是一個增強版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做棕孙。HttpURLConnection沒有提供的有些功能龄句,HttpClient也提供了,但它只是關注于如何發(fā)送請求散罕、接收響應分歇,以及管理Http的連接》
《Android已經成功集成了HttpClient:Android6.0開始,已經將HttClient框架從AndroidSDK中移除》
】
《注意:需要加入外部的Java包欧漱。
》
【
publicclass Demo {
public static void main(String[] args){
// TODO Auto-generated methodstub
//?????????????? doGetByHttpClient();
doPostByHttpClient();
}
private static voiddoPostByHttpClient() {
// TODO Auto-generated methodstub
HttpClient client = null;
try {
client = newDefaultHttpClient();
HttpPost post = newHttpPost("http://api.k780.com:88/");
//保存請求參數(shù)的集合對象
Listlist = new ArrayList<>();
//將請求參數(shù)封裝成對象存入集合中职抡,每一個NameValuePair對象封裝了一組鍵值對
list.add(newBasicNameValuePair("app", "weather.today"));
list.add(new BasicNameValuePair("weaid","1"));
list.add(newBasicNameValuePair("appkey", "15250"));
list.add(newBasicNameValuePair("sign","f88a5cecc3cbd37129bc090c0ae29943"));
list.add(newBasicNameValuePair("format", "json"));
HttpEntity httpEntity = newUrlEncodedFormEntity(list);
post.setEntity(httpEntity);
HttpResponse response =client.execute(post);
int code =response.getStatusLine().getStatusCode();
if(code == 200){
InputStream is =response.getEntity().getContent();
String result =readStream(is);
System.out.println(result);
}
} catch(UnsupportedEncodingException e) {
// TODOAuto-generated catch block
e.printStackTrace();
} catch(IllegalStateException e) {
// TODOAuto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}finally{
if(client != null){
client.getConnectionManager().shutdown();
client =null;
}
}
}
private static void doGetByHttpClient(){
// TODO Auto-generated methodstub
HttpClient client = null;
try {
client? = new DefaultHttpClient();
HttpGet get = newHttpGet("http://api.k780.com:88/?app=weather.today&weaid=1&&appkey=15250&sign=f88a5cecc3cbd37129bc090c0ae29943&format=json");
//訪問網絡資源
HttpResponseresponse = client.execute(get);
//獲取狀態(tài)碼
int code=response.getStatusLine().getStatusCode();
if(code == 200){
InputStreamis = response.getEntity().getContent();
Stringresult = readStream(is);
System.out.println(result);
}else{
throw newRuntimeException("網絡訪問失敗:"+code);
}
} catch(ClientProtocolException e) {
// TODOAuto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}finally{
if(client !=null){
client.getConnectionManager().shutdown();
client =null;
}
}
}
public static StringreadStream(InputStream is) throws IOException{
ByteArrayOutputStream baos =new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=is.read(buf))!=-1){
baos.write(buf, 0,len);
}
return newString(baos.toByteArray(), "utf-8");
}
}
】
【
K780數(shù)據(jù)網误甚,測試賬號
《Appkey:15250???? Secret:2bbebb3e480a850df6daca0c04a954e1
Sign:f88a5cecc3cbd37129bc090c0ae29943》
】
1.6????示例使用Post和Get請求網絡數(shù)據(jù)
【
publicclass NetPostGet {
/**
* @param args
*/
public static void main(String[] args){
// TODO Auto-generated methodstub
// doGet();
doPost();
}
// 使用post方式請求網絡數(shù)據(jù)
private static void doPost() {
HttpURLConnection conn =null;
try {
URL url = newURL("http://api.k780.com:88/");
conn =(HttpURLConnection) url.openConnection();
String data ="app=weather.today&weaid=1&&appkey=15250&sign=f88a5cecc3cbd37129bc090c0ae29943&format=json";
conn.setRequestMethod("POST");
conn.setReadTimeout(5000);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",data.length() + "");
// post網絡訪問必須實現(xiàn)
conn.setDoInput(true);
conn.setDoOutput(true);
// 注意要將請求的內容寫到請求體中去
conn.getOutputStream().write(data.getBytes());
conn.connect();
int code =conn.getResponseCode();
if (code == 200) {//表示訪問成功
InputStreamis = conn.getInputStream();
System.out.println(readStream(is));
} else {
System.out.println("網絡數(shù)據(jù)訪問失敗:" + code);
}
} catch(MalformedURLException e) {
// TODOAuto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
conn =null;
}
}
}
// 使用get方式請求網絡數(shù)據(jù)
private static void doGet() {
HttpURLConnection conn =null;
try {
URL url = new URL(
"http://api.k780.com:88/?app=weather.today&weaid=1&&appkey=15250&sign=f88a5cecc3cbd37129bc090c0ae29943&format=json");
conn =(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
int code =conn.getResponseCode();
if (code == 200) {
InputStreamis = conn.getInputStream();
System.out.println(readStream(is));
} else {
System.out.println("獲取數(shù)據(jù)失敗:" + code);
}
} catch(MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
conn =null;
}
}
}
public static StringreadStream(InputStream is) throws IOException {
ByteArrayOutputStream baos =new ByteArrayOutputStream();
int len = 0;
byte[] buf = new byte[1024];
while ((len = is.read(buf))!= -1) {
baos.write(buf, 0,len);
}
return newString(baos.toByteArray(), "utf-8");
}
}
】
【
publicclass HttpUtils {
private static final int TIMEOUT =10000;
//返回一個字節(jié)數(shù)組
public static byte[] doGet(Stringpath){
try {
URL mUrl = newURL(path);
HttpURLConnectionconn = (HttpURLConnection)mUrl.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(TIMEOUT);
conn.setReadTimeout(TIMEOUT);
conn.connect();
int code =conn.getResponseCode();
if(code == 200){
return readStream(conn.getInputStream());
}else{
throw newRuntimeException("網絡訪問失敻克Α:"+code);
}
} catch(MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static byte[] doPost(String url,String params) {
HttpURLConnection conn =null;
try {
URL mUrl = newURL(url);
conn =(HttpURLConnection) mUrl.openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(TIMEOUT);
conn.setReadTimeout(TIMEOUT);
// 設置請求屬性
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",params.length()+"");
// Post請求必須要寫以下兩行代碼
conn.setDoInput(true);
conn.setDoOutput(true);
// 將請求參數(shù)寫到請求體中
conn.getOutputStream().write(params.getBytes());;
conn.connect();
int code =conn.getResponseCode();
if(code == 200) {
returnreadStream(conn.getInputStream());
} else {
throw newRuntimeException("網絡訪問失敗:"+ code);
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(conn != null) {
conn.disconnect();
conn =null;
}
}
}
//返回一個字符串
public static String doGetStr(Stringpath) throws IOException{
byte[] data = doGet(path);
return new String(data, "utf-8");
}
private static byte[]readStream(InputStream is) throws IOException{
ByteArrayOutputStream baos =new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len =0;
while((len =is.read(buf))!=-1){
baos.write(buf, 0,len);
}
return baos.toByteArray();
}
}
】
【
在Android中對網絡請求最基本的實現(xiàn)有兩種
1窑邦、? HttpURLConnection
是JDK自帶的實現(xiàn)方式擅威,實現(xiàn)方式相對比較繁瑣,也比較靈活
2冈钦、? HttpClient框架
底層代碼還是基于HttpURLConnection,只是對HttpURLConnection進行了更深層次的封裝
是apache開源組織開發(fā)的開源框架郊丛,實現(xiàn)方式相對簡單一些,相對HttpURLConnection來說瞧筛,沒有那么靈活
Android在SDK(SoftwareDevelopment Kit)中已經集成了HttpClient框架
不過厉熟,Android在6.0開始,就已經將HttpClient框架從SDK中移除了
】