?????原來準備簡單點,用一篇文章介紹完JSP的,沒想到細節(jié)很多泪姨。這是第三篇也是最后一篇,這三篇文章介紹了基本的JSP知識饰抒,很多名詞概念和用法肮砾,一定要在實踐項目中使用之后才會有更加親切的體會。第三篇接著上篇介紹的JSP內置對象袋坑。
?????上篇我們說過仗处,在我們的響應用戶請求的方法_jspservice()方法的頭部,定義和初始化了一些局部變量。他們其實就是我們現在說的jsp內置對象婆誓,通過這些對象所封裝的方法吃环,我們可以完成一些關于數據共享,數據傳輸旷档,瀏覽器響應等操作模叙。
?????第一個內置對象是,application鞋屈。熟悉.net的朋友可能知道范咨,在.net中,可以使用session厂庇,cookies來實現多個不同頁面之間數據的共享渠啊,在我們JSP 中上述有著更加完善的共享數據機制,上述的session和cookies只是其中的一部分权旷。所有被application設置訪問范圍的數據在整個web應用中都是可見的替蛉,無論你是jsp頁面還是servlet頁面,只要是位于當前的web應用中的頁面都是可以訪問該數據的拄氯。這叫全局可見性躲查,是所有共享數據中范圍最大的。具體的使用方法如下:
<html>
<head>
<title>1</title>
</head>
<body>
<h1>index.jsp</h1>
<%application.setAttribute("name","張三");%>
</body>
</html>
<html>
<head>
<title>2</title>
</head>
<body>
<h1>convert.jsp</h1>
<%=application.getAttribute("name")%>
</body>
</html>
?????訪問過index頁面之后訪問convert頁面译柏,可以看到我們在index頁面設置的全局性變量镣煮,在另外的頁面是可以訪問的到的。這種是將數據設置在整個web應用下的鄙麦,所以在可以放在更低范圍內的情況下(后文會介紹在更小的范圍設置共享數據)典唇,盡量還是不要設置在全局下,因為這樣很有可能在不經意之間被修改了值產生數據不一致性胯府。
?????application對象的第二個作用是可以讀取web.xml中的配置信息介衔,這是一種可能會經常使用到的操作。因為我們的數據庫用戶名和密碼等參數的配置一般都是配置在web.xml中的骂因,當我們在程序中需要用到的時候炎咖,就可以考慮這種操作來讀取配置信息。
/首先在web.xml文件中配置一下信息/
<html>
<head>
<title>1</title>
</head>
<body>
<h1>index.jsp</h1>
<%=application.getInitParameter("a")%>
</body>
</html>
?????通過上述操作侣签,我們成功的訪問了配置信息內容塘装,web.xml中< context-param>標簽中的就是類似于鍵值對的作用,子標簽配置的是name和value和我們的param動作指令的傳參是類似的影所,之后便可以同過方法getInitParameter("name")來獲取對應的value的值蹦肴。
?????第二個內置對象,pageContext猴娩。這是一個非常大佬的對象阴幌,他可以獲取其他的內置對象勺阐。
ServletReques getRequest(); //獲取Request對象
ServletResponse getResponse(); //獲取Response對象
SerletConfig getServletConfig();//獲取config對象
ServletContext getServletContext();//獲取application對象
HttpSession getSession(); //獲取session對象
?????以上的有些對象我們說了,有些對象會在后文中說明矛双,有些暫時不會介紹渊抽,原因是他們不是很常用。
?????pageContext對象的主要作用還是對共享數據的范圍設定议忽。
pageContext.setAttribute("name","li",pageContext.PAGE_SCOPE); //設置變量位于當前page范圍內可見
pageContext.setAttribute("name","li",pageContext.REQUEST_SCOPE); //設置變量位于本次請求中可見
pageContext.setAttribute("name","li",pageContext.SESSION_SCOPE); //設置變量位于當前會話范圍內可見(就是瀏覽器關了就沒了)
pageContext.setAttribute("name","li",pageContext.APPLICATION_SCOPE); //設置變量位于當前Web應用范圍內可見
當然懒闷,對應的獲取方法是:pageContext.getAttribute("name")。
第三個內置對象是栈幸,request對象愤估。這個對象封裝了用戶的某次請求的所有內容,有瀏覽器自動生成的請求頭速址,還有用戶提交的請求參數玩焰。請求頭對于我們來說暫時可能沒怎么使用到,但是請求參數還是需要好好的研習一下的芍锚。下面提供了幾個獲取請求參數的方法:
String getParameter(String paramName) //獲取指定name的參數值
Map getParameterMap() //獲取所有請求參數名和請求參數值昔园,以鍵值對的形式返回
Enumeration getParameterNames() //獲取所有請求參數名構成的Enumeration集合
String[] getParameterValues(String name) //獲取指定name的所有參數值,可能一個參數name對應了多個參數值
<html>
<head>
<title>1</title>
</head>
<body>
<h1>提交表單</h1>
<form method="get" action="index.jsp">
<input type="text" name="name" />
<input type="text" name="age" />
<input type="submit" value="提交" />
</form>
</body>
</html>
<html>
<head>
<title>1</title>
</head>
<body>
<h1>index.jsp</h1>
<%=request.getParameter("name")%>
<%=request.getParameter("age")%>
</body>
</html>
?????相信大家已經知道結果了并炮,我們知道瀏覽器的請求方法是有兩種的默刚,Get和Post請求,兩種請求方式的優(yōu)劣相信大家都知道逃魄,此處不再啰嗦羡棵。雖然是兩種請求方式,但是我們在獲取請求參數的數值的時候是一樣的方法嗅钻,不要做另外的改變。以上至演示了一種形式店展,其他形式獲取參數的情況大家可以自行測試养篓。
?????request對象還有一個操作也是經常會做的,官方說法赂蕴,操作request范圍的屬性柳弄。其實就是將某個變量放到request請求參數中,在接受頁面出可以接受該參數概说。
<html>
<head>
<title>1</title>
</head>
<body>
<h1>index.jsp</h1>
<%request.setAttribute("abc","hello");%>
//實現轉發(fā)
<jsp:forward page="convert.jsp" />
</body>
</html>
<html>
<head>
<title>2</title>
</head>
<body>
<h1>convert.jsp</h1>
<%=request.getAttribute("abc")%>
</body>
</html>
?????我們可以簡單的理解為碧注,這個操作就是將指定的參數添加到請求本頁面的這個request對象中,一旦此頁面實現跳轉糖赔,必然可以攜帶者這個參數轉發(fā)到另外的頁面中萍丐。
?????最后,我們說說這個response內置對象放典。剛才我們介紹的request是處理用戶請求的逝变,主要是接受用戶傳入的請求參數基茵,或者解析請求頭信息等。而正真決定怎么響應我們用戶的是response對象壳影。
?????首先我們看看第一個作用拱层,response的getOutputStream()方法,這個方法返回響應輸出字節(jié)流宴咧,一個OutputStream對象根灯。我們在介紹流那塊知識的時候說過,每個流都會綁定一個文件掺栅,這個文件可以是字節(jié)數組烙肺,或者磁盤上的實際文件,因為這些操作最終都會流到實際的文件中柿冲。(不可能是一個抽象不存在的文件茬高,那我們的一切操作豈不是操作空氣,又沒有改變什么)假抄,此處可以將getOutputStream方法理解為綁定了當前請求的瀏覽器怎栽,也就是我們隊流進行寫入會寫到瀏覽器中∷薇ィ看個例子:
<html>
<head>
<title>1</title>
</head>
<body>
<h1>index.jsp</h1>
<%
response.setHeader("content-type", "text/html;charset=UTF-8");
OutputStream outputStream = response.getOutputStream();
String str = "hello world";
byte[] buffer = str.getBytes();
outputStream.write(buffer);
%>
</body>
</html>
?????結果顯而易見熏瞄,但是不要忘記引入Java.io.* 這個包,否則會報錯谬以,不能識別OutputStream强饮。
?????第二個用法,頁面重定向为黎。使用的是方法邮丰,response.sendRedirect(String path)。這個頁面重定向和之前的forward動作指令是不一樣的铭乾,之前的forward指令不會丟棄當前request的請求參數剪廉,而這也頁面重定向會丟棄所有的請求參數,重新開一個request炕檩,并且地址欄的地址也是會隨之改變的斗蒋。具體代碼很簡單,不演示了笛质,要不然就寫不完了泉沾。
?????最后一個response對象的操作是,增加cookies妇押,我們知道cookies是保存在用戶本機電腦上的跷究,對服務器帶寬沒什么影響,但是會有不安全隱患舆吮,如果被用戶刪了怎么辦揭朝?但是我們還是會經常的使用它的队贱,現在我們看看怎么使用這個cookies。
<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.io.*,javax.servlet.http.Cookie" %>
<html>
<head>
<title>1</title>
</head>
<body>
<h1>index.jsp</h1>
<%
Cookie c = new Cookie("name","zhangsan");
c.setMaxAge(3600);
response.addCookie(c);
%>
<%
Cookie[] cookies = request.getCookies();
for(Cookie a : cookies){
if(a.getName().equals("name")){
out.println(a.getValue());
}
}
%>
</body>
</html>
?????設置cookie只需要三個步驟潭袱,在上述代碼中已經得到體現柱嫌,第一步,創(chuàng)建cookie對象屯换,沒引入cookie包的會報錯的编丘,第二步,設置cookie的聲明周期彤悔,也就是什么時候過期失效嘉抓,單位毫秒,第三部使用response.addCookie()方法設置cookie晕窑。
?????cookie的讀出抑片,我覺的是設計的不合理的地方,它竟然需要將所有的cookie全部讀取出來杨赤,然后需要遍歷找到我們需要的cookie敞斋。當然可能.net中的底層也是這么實現的,但是人家提供的接口就很簡潔疾牲,根據名稱就可以直接找到值植捎。
?????至此,JSP的基本知識就介紹完了阳柔,其實還是不全面焰枢,但是我會在繼續(xù)學習中進行補充的。如果文章哪里有錯誤舌剂,歡迎大家指出來济锄。