1. JSP的本质是Servlet,当用户向指定Servlet发送请求时,Servlet利用输出流动态生成HTML页面。
JSP页面由系统编译成Servlet,Servlet再负责相应用户请求。JSP其实是Servlet的一种简化。
JSP页面生成的Servlet放在work路径对应的Web应用下。
2. JSP页面工作原理:
(1)客户端(浏览器)向服务器发出请求;
(2)如果该JSP页面第一次收到请求,先编译JSP文件,生成对应的Servlet。
如果该JSP页面已有对应的Servlet,则服务器会根据请求动态生成标准的HTML页面。
(3)服务器返回标准HTML页面给客户端。
3. 当JSP被编译成Servlet时,JSP注释、JSP声明、JSP输出表达式、JSP脚本、JSP编译指令是否都在Servlet中。如果在,分别在哪个位置?
4. JSP的编译指令和动作指令的区别
(1)JSP的编译指令是通知JSP引擎的消息,在JSP编译成Servlet时起作用,它不直接生成输出。编译指令都有默认值。
(2)JSP的动作指令只是运行时的动作,是JSP脚本的标准化写法,可以用JSP脚本替换。
5. JSP有3个编译指令,分别是page、include和taglib,作用分别是什么?
6. JSP有7个动作指令,分别是forward、include、plugin、param、useBean、setProperty、getProperty。
使用语法:<jsp:动作指令名 属性名="属性值"/>或<jsp:动作指令名 属性名="属性值"></jsp:动作指令名>
7. JSP编译指令include(静态导入/包含)和动作指令include(动态导入/包含)的区别:
(1)静态导入是将被导入页面的代码完全融入,两个页面融合成一个整体Servlet;而动态导入则在Servlet中使用include方法来引入被导入页面的内容。
(2)静态导入时被导入页面的编译指令会起作用;而动态导入时被导入页面的编译指令则失去作用。
(3)动态包含还可以增加额外的参数。
8. JSP有9个内置对象,分别是application, config, session, request, response, page, pageContext, out, exception.
9个内置对象的作用分别是:
(1)application: javax.servlet.ServletContext的实例,该实例代表jsp页面所属的Web应用本身,可用于JSP页面,或者在Servlet之间交换信息。
(2)config: javax.servlet.ServletConfig的实例,该实例代表JSP页面的配置信息。该对象更多地在Servlet中有效。
(3)session: javax.servlet.http.HttpSession的实例,该实例代表一次会话。从浏览器和站点/应用建立连接(会话开始),到浏览器关闭(会话关闭),这是一次会话。
(4)request: javax.servlet.http.HttpServletRequest的实例,该对象封装了一次请求。客户端的请求参数都被封装在该对象里。
(5)response: javax.servlet.http.HttpServletResponse的实例,代表服务器对客户端的相应。通常很少使用该对象相应,而是使用jsp页面的输出流对象out来输出字符串给客户端。如果要生成非字符串,则可以使用response。它通常用于获取输出、转发、重定向请求等。
(6)page: java.lang.Object的实例,该实例代表页面本身,即Servlet实例本身,即this。其类型就是生成的Servlet类,能用page的地方就可以用this。
(7)pageContext: javax.servlet.jsp.PageContext的实例,该实例代表JSP页面上下文,使用该对象可以访问页面中的共享数据,常用于获取当前JSP页面所属的application和config、session、out、exception。
(8)out: javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流,用于输出字符串,形成HTML页面。
(9)exception: java.lang.Throwable的实例,该实例代表其他页面中的异常和错误。只有当JSP页面为错误处理页面,即编译指令page 的isErrorPage属性为true时,该JSP页面才能使用该对象。
9. Web服务器的实现原理:Web应用,常称为B/S架构(也可叫“请求/响应”架构)的应用,但也可看做C/S架构的应用。
浏览器负责完成的事情:
(1)向远程服务器发送请求;
(2)读取远程服务器返回的字符串数据;
(3)负责根据字符串数据渲染出一个丰富多彩的页面
Web服务器负责的工作:
(1)等待客户端连接;
(2)接收到用户请求,启动单独的线程;
(3)使用I/O流读取用户的请求数据;
(4)从请求数据中解析请求参数;
(5)处理用户请求;
(6)生成响应数据;
(7)使用I/O流向客户端发送请求数据。
10. Web应用里的JSP页面、Servlet等程序都将由Web服务器来调用,JSP、Servlet之间通常不会相互调用,那么,JSP、Servlet之间如何交换数据?
JSP和Servlet之间交换数据是通过4个类似Map结构——application、session、request和page。
它们类似银行的角色——把数据放入这四个结构,再从这四个结构拿数据。
JSP中通过application、session、request和pageContext这四个内置对象来分别操作这application、session、request和page四个范围的数据。
11. 可以使用PageContext获取各属性所在的范围(pageContext.getAttributesScope(属性名)),其中这些范围获取的都是整型变量,这些整型变量分别对应如下4个生存范围。
PageContext.PAGE_SCOPE = 1: 对应page生存范围。
PageContext.REQUEST_SCOPE = 2: 对应request生存范围。
PageContext.SESSION_SCOPE = 3: 对应session生存范围。
PageContext.APPLICATION_SCOPE = 4: 对应application生存范围。
PageContext类提供了如下两个方法来访问page、request、session、application范围的变量。
getAttribute(String name);
getAttribute(String name, int scope); scope可以是以上的4个值。
12. 如果post请求的请求参数里包含非西欧字符,则必须在获取请求参数之前先调用setCharacterEncoding()方法设置编码的字符集。
如果发送请求的表单页采用gb2312字符集,该表单页发送的请求也应采用gb2312字符集,即request.setCharacterEncoding("gb2312");
13. 如果GET请求值里包含了非西欧字符,则获取这些参数比较复杂。通常有两种方法。
(1)先获取请求里包含的字符串,再使用URLDecoder以GBK的方式解码字符串,最后分割字符串得到相应参数的参数名和参数值。代码如下:
String rawQuery = request.getQueryString();
String queryStr = java.net.URLDecoder.decode(rawQuery, "gbk");
//以&分解查询字符串
String paramPairs = queryStr.split("&");
for(String paramPair : paramPairs)
{
//以=来分解请求参数名和值,nameValue[0]为参数名,nameValue[1]为参数值。
String[] nameValue = paramPair.split("=");
}
(2)获取对应参数名的值,先将其重新以ISO-8859-1格式分解成字节数组,最后以Ggb2312的格式将字节数组解码成字符串。
//获取原始的请求参数
String rawname = request.getParameter("name");
//将请求参数值使用ISO-8859-1字符串分解成字节数组
byte[] rawBytes = rawname.getBytes("ISO-8859-1");
//将字节重新解码成字符串
String name = new String(rawBytes, "gb2312");
中文乱码原因见《Java web开发中的编码问题》一文。
14. HttpServletRequest类提供了forward和include方法代替JSP所提供的forward和include功能。
如下代码行可以将a.jsp页面include到本页面中。
request.getRequestDispatcher("/a.jsp").include(request, response);
如下代码行则可以将请求forward到a.jsp页面:
request.getRequestDispatcher("/a.jsp").forward(request, response);
注:使用request的getRequestDispatcher(String path)方法时,该path字符串必须以斜线开头。
15. forward(转发)和redirect(重定向)的区别
16. response对象的主要功能:
(1)响应生成非字符响应
(2)重定向(response.sendRedirect(path));
(3)增加Cookie(Cookie放在客户端机器上)
添加Cookie的步骤:
(1)创建Cookie实例,Cookie的构造器为Cookie(String name, String value);
(2)设置Cookie的生命期限
(3)向客户端写Cookie。