目录
深入分析pageContext对象
pageContext只能设置页面上下文的属性信息,但是在整个JSP设计里面,赋予了pageContext更多的功能,这个类可以设置四种属性范围的保存,在此类中有如下的几个方法:
-
设置属性:public abstract void setAttribute(String name, Object value, int scope)
-
取得属性:public abstract Object getAttribute(String name, int scope)
-
删除属性:public abstract void removeAttribute(String name, int scope)
发现在这三个方法之中都会有一个scope的int变量,而此变量内容就是描述你的属性范围,在pageContext里面提供有四种常量描述四种范围:
-
PAGE范围:public static final int PAGE_SCOPE
-
REQUEST范围:public static final int REQUEST_SCOPE
-
SESSION范围:public static final int SESSION_SCOPE
-
APPLICATION范围:public static final int APPLICATION_SCOPE
范例:设置属性
<%@ page pageEncoding="UTF-8" %>
<%@ page import="java.util.*" %>
<% // 设置属性
pageContext.setAttribute("name", "ren");
pageContext.setAttribute("birthday", new Date(), pageContext.REQUEST_SCOPE);
%>
<jsp:forward page="page_scope_b.jsp"/>
范例:取得属性
<%@ page pageEncoding="UTF-8" %>
<%@ page import="java.util.*" %>
<% // 设置属性
String myName = (String) pageContext.getAttribute("name");
Date myBirthday = (Date) pageContext.getAttribute("birthday", pageContext.REQUEST_SCOPE);
%>
<h1>属性内容:<%=myName %> , <%=myBirthday %></h1>
四种属性范围都可以使用pageContext完成,但是考虑到实际情况这样的操作很少这样做。一般还是通过不同的对象描述不同的范围,而且关键问题是pageContext只能够在JSP页面中使用。
request内置对象
request内置对象是web开发中最为常用的对象,因为web开发的特点就是交互性,而交互性的体现主要是通过request来接收用户的请求信息,request对应的类型是javax.servlet.http.HttpServletRequst接口,该接口定义如如下:
- public interface HttpServletRequest extends ServletRequest
可以发现HttpServletRequest是javax.servlet.ServletRequest的子接口,
接收请求参数
在之前使用过的getParameter()方法的具体定义:public String getParameter(String name),在之前是使用表单进行参数的提交。
范例:定义表单
<form action="input_do.jsp" method="post">
姓名:<input type="text" name="name" id="name">
<input type="hidden" id="mid" name="mid" value="ren">
<input type="submit" value="提交">
</form>s
此时定义了两个参数,其中表单之中如果某些数据不需要用户输入,而且又需要将数据结合一起提交,那么就采用隐藏域的形式来进行处理。
范例:定义参数接收页面
<%@ page pageEncoding="UTF-8"%>
<%
String name = request.getParameter("name");
String mid = request.getParameter("mid") ;
%>
<h1>name=<%=name %> , mid=<%=mid %></h1>
发现表单进行提交的时候可以设置method,用于描述不同的表单提交类型,用于描述不同的表单提交类型,有两种提交方式(在HttpServletRequest接口里面有一个getMethod()可以取得提交模式:
-
GET提交:用户直接访问指定的页面就属于get提交(例如:直接访问input_do.jsp),如果在表单上使用则会将提交内容附加在目标地址之后,例如:http://localhost/loginProject/input_do.jsp?name=57&mid=ren;
|- 格式:XXX地址?参数名称=参数内容&参数名称=参数内容...
|- 地址重写提交:http://localhost/loginProject/input_do.jsp?name=57&mid=ren
- POST提交:只有在表单上才拥有,提交的表单只显示目标地址,而不显示提交内容
总结:request.getParameter()方法可以接收三类参数:
- 表单提交参数:POST、GET;
- 地址重写参数:?name=value&name=value.....
- 标签指令中传递的参数:<jsp:param.../>
处理请求乱码
所有的表单一定不可避免要进行中文数据的输入,发现在现在的Tomcat版本里面,使用地址重写提交才可以显示中文。下面需要解决POST、GET提交的乱码问题,这个时候就属于传输的编码,在ServletRequest接口里面提供有两个与编码操作有关的方法:
-
取得设置的编码:public String getCharacterEncoding()
-
设置请求编码:public void setCharacterEncoding(String env) throws UnsupportedEncodingException
范例:解决乱码
<%
request.setCharacterEncoding("UTF-8") ;
String name = request.getParameter("name");
String mid = request.getParameter("mid") ;
%>
我的不起作用了,受到版本的影响,可能会变,
以后JSP的页面都采用以上的方法进行编码的设置。
接收一组参数
对于getParameter()方法一次只能接收一个参数,如果前台给出的表单时一堆复选框,这个时候就无法正常接收了。如果要想接收一组参数就需要使用:public String[] getParameterValues(String name);
范例:定义表单的复选框
<form action="input_do.jsp" method="post">
姓名:<input type="text" name="name" id="name" value="ren57"><br>
兴趣:
<input type="checkbox" name="inst" id="inst" value="swiming"> swiming
<input type="checkbox" name="inst" id="inst" value="music"> music
<input type="checkbox" name="inst" id="inst" value="book"> book<br>
<input type="submit" value="提交">
</form>
范例:定义接收操作
<%@ page pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("utf-8") ;
String name = request.getParameter("name");
String inst[] = request.getParameterValues("inst") ;
%>
<h1>当前的HTTP提交方法:<%=request.getMethod() %></h1>
<h1>name=<%=name %> </h1>
<h1>inst = <%=java.util.Arrays.toString(inst)%> </h1>
在以后开发中可能涉及到批量删除操作,批量删除有可能涉及到复选框的多选,接收时注意方法。
接收全部请求参数的名称
在ServletResquest之中还定义有一个功能,这个功能能够定义用户提交的所有的参数名称信息,该方法定义如下:
- 取得全部参数的名称:public Enumeration<String> getParameterNames()
范例:观察getParamemter()方法的使用
<form action="input_show.jsp" method="post">
姓名:<input type="text" name="name" id="name" value="ren57"><br>
兴趣:
<input type="checkbox" name="**inst" id="inst" value="swiming"> swiming
<input type="checkbox" name="**inst" id="inst" value="music"> music
<input type="checkbox" name="**inst" id="inst" value="book"> book<br>
<input type="submit" value="提交">
</form>
<%@ page pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%
request.setCharacterEncoding("utf-8") ;
// 取得全部的请求参数的名称
Enumeration<String> enu = request.getParameterNames() ;
while(enu.hasMoreElements()){
String paramName = enu.nextElement() ;
if(paramName.startsWith("**")){
%>
<li><%=paramName %>= <%= java.util.Arrays.toString(request.getParameterValues(paramName)) %> </li>
<%
} else {
%>
<li><%=paramName %>= <%= request.getParameter(paramName) %> </li>
<%
}
}
%>
此操作方法与后续的项目涉及有关。
在ServletResquest接口之中还提供有取得参数Map集合的方法:
<%@ page pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%
request.setCharacterEncoding("utf-8") ;
Map<String,String[]> paramMap = request.getParameterMap();
Iterator<Map.Entry<String,String[]>> iter = paramMap.entrySet().iterator() ;
while(iter.hasNext()){
Map.Entry<String, String[]> me = iter.next() ;
%>
<li> <%=me.getKey() %> = <%=java.util.Arrays.toString(me.getValue()) %></li>
<%
}
%>
如果使用的是getParameterNames()方法取得的只是参数,而要想取得参数参数的内容则需要依靠getParameter()方法完成。如果使用了getParameterMap()方法会将参数以及对应的内容以Map集合的形式返回,但是所有的参数接收都需要使用String[]完成。
取得上下文名称
这个方法定义:public String getContextPath(),该方法取得的是虚拟目录的名称信息。
范例:观察此方法的取得
<%@ page pageEncoding="UTF-8"%>
<%
String contextPath = request.getContextPath() ;
%>
<h1><%=contextPath %></h1>
在任何一个页面里面(*.jsp)一定会引入到类似于:*.jsp、*.css、*.jpg之类的文件,可能会出现文件的更改,这个时候最好采用文件的绝对定位,就需要使用contextPath完成绝对路径。
在以后的开发中一定要编写资源绝对路径的引用形式。
request其它操作
request的对象主要是取得客户端发送来的信息,除了之前的参数之外也可以取得一些附加信息。
取得客户端的IP地址:public String getRemoteAddr()
范例:取得客户端的信息
<%@ page pageEncoding="UTF-8"%>
<h1>客户端地址:<%=request.getRemoteAddr() %></h1>
<h1>客户端端口:<%=request.getRemotePort() %></h1>
<h1>客户端主机:<%=request.getRemoteHost() %></h1>
可以通过以下的方法取得当前页面路径的相关内容:
- 取得虚拟路径后面的访问路径:public String ServletPath() ;
- 取得访问协议:public String getProtocol() ;
- 取得请求模式:public String getScheme() ;
- 取得服务的主机名称:public String getServerName();
- 取得服务器端口:public String getServerPort() ;
通过拼凑以上方法就可以得到,完整的路径:
需要考虑一个实际问题,如果你的页面里面可能导入500张图片,200个脚本,100个样式。那么就意味着这个basepath要写近1000遍,所以最好设置一个统一的资源定位,如下:
一旦使用了“<base>”ase>”标签之后,以后外部资源的加载的时候会直接定位到此标签定义的路径后再进行资源的读取。