JSP运行原理:
每个JSP页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的
调用方式进行调用。
由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。
JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特
意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。
Jsp九大隐式对象
内置对象/作用域(每一种作用域的生命周期是不一样的):
1, application 全局作用域
2, session 会话作用域
3, request 请求作用域
4, pageContext 页面作用域
内置对象
5, response 响应对象
6, out 输出流对象
7, page 当前页面对象的实例
8, exception 异常
9, config ServletConfig/FilterConfig对象
优先级 (按照生命周期的长短):
application > session > request > pageContext
request对象:
request对象是HttpServletRequest这个类的实例
常用方法:‘’
String getParameter(String name)---返回name指定的参数的值
String[] getParameterValues(String name)---返回一个数组, 是包含那个参数名的所有的人,复选框等提交内容
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="test2.jsp" method="post"> username: <input type="text" name="username" /><br> password: <input type="text" name="password" /><br> 1<input type="checkbox" name="ct" value="5" /><br> <input type="submit" value="提交" /> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% String username = request.getParameter("username"); String password = request.getParameter("password"); String[] cts = request.getParameterValues("ct"); out.print("request.getParameter()接收到的参数: " + username+"<br>"); out.print("request.getParameter()接收到的参数: " + password); for (String s : cts) { out.print("<br>"+"复选框的值: " + s ); } %> </body> </html>
void setAttribute(String, Object)---设置某个作用域中的属性
Object getAttribute(String name)---获取某个作用域中的属性
//设置某个作用域中的属性 <%request.setAttribute("req", 123); %> //获取某个作用域中的属性 <%=request.getAttribute("req")%>
String getRealPath(String path)---返回传入的这个路径的物理路径
String getContextPath()---返回上下文路径
String getServerName()---返回请求服务器的主机名
String getContentType()---返回请求体的MIME类型
String getprotocol()---返回请求用的协议类型和版本号
int getServerPort()---获取服务器的端口号
int getContentLength()---返回请求体的长度(单位是字节)
String getRemoteAddr()---返回发送此请求的客户端的IP地址
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <br> --String getRealPath(String path)---返回传入的这个路径的物理路径 <%=request.getRealPath("/") %> <br> --String getContextPath()---返回上下文路径 <%=request.getContextPath() %> <br> --String getServerName()---返回请求服务器的主机名 <%=request.getServerName() %> <br> --String getContentType()---返回请求体的MIME类型 <%=request.getContentType() %> <br> --String getprotocol()---返回请求用的协议类型和版本号 <%=request.getProtocol() %> <br> --int getServerPort()---获取服务器的端口号 <%=request.getServerPort() %> <br> --String getRemoteAddr()---返回发送此请求的客户端的IP地址 <%=request.getRemoteAddr() %> <br> --int getContentLength()---返回请求体的长度(单位是字节) <%=request.getContentLength() %> </body> </html>
解决request中出现中文乱码的问题
post方式:
通过使用request.setCharacterEncoding("utf-8")来设置
get方式:
通过修改Tomcat服务器中的server.xml配置文件来设置
<% request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); %>
Session对象
session指的是用户在进入一个网站开始到关闭浏览器的时间, Tomcat服务器默认的session有效时间是30分钟, 也就是说, 打开一个网站30分钟之内没有动作, session对象同样也会失效
session存在服务器的内存中, 服务器中不同的用户对应的session也是不同的, 所以服务器用来判断当前登录的用户是否是同一个的时候就需要session
session对象是HttpSession的实例
常用方法:
long getCreationTime()---返回session对象创建的时间
String getId()---返回一个sessionid, 是唯一的
void setAttribute()---设置一个属性和一个属性值
Object getAttribute()---获取某个属性的属性值
String[] getValueNames()---以数组的形式获取session对象中所有可用属性的属性名
setMaxInactiveInterval()---设置session经过多长时间之后失效(默认30分钟)
getMaxInactiveInterval()---设置session的失效时间(单位是秒)
session的生命周期:
创建: 当用户第一次访问某个jsp或者servlet的时候, 服务器就会为当前的访问创建一个session, 并生成一个sessionId, 每次客户端向服务器发送请求的时候, 都会将这个sessionId带过去进行验证
活动: 在这个页面的各种活动, 比如通过超级连接打开另一个页面, 或者进行各种增删改查的操作, session失效除非要等到浏览器的相关页面全部关闭, 或者session超时, 当再次访问的时候会创建一个新的session, 但是原来的session还会存在, 只不过没有任何请求再带着那个旧的sessionId让服务器去验证了
销毁:
三种方法可以销毁session
1, 调用session.invalidate()方法
2, session自己过期了
设置session过期时间也可以在web.xml中设置
<session-conf>
<session-timeout>
10<!-- 单位是分钟 ! -->
</session-timeout>
</session-conf>
3, 服务器重新启动
if(obj!=null) { User u = (User)obj; if(password.equals(u.getPassword())) { session.setAttribute("currentUser", u);//设置验证登录,如果直接访问主页,验证时获取不到user,跳转 response.sendRedirect("main.jsp"); } else { out.print("密码不对啊 !"); } }
<% Object obj1 = session.getAttribute("currentUser"); if (obj1 == null) { response.sendRedirect("denglu.jsp"); } %>
application对象
application对象是一个全局对象, 生命周期为服务器启动一直到服务器停止, 在这个对象里面可以存放一些全局变量
setAttribute(String, Object)---设置某个属性和属性值
getAttribute(String)---获得某个属性的值
getAttributeNames()---获取application对象中所有的属性名
if(obj==null){ List list =new ArrayList(); list.add(says); application.setAttribute("liuyanjihe",list); }else{ List<Says> list=(List)obj; list.add(says); application.setAttribute("liuyanjihe",list); }
Object obj=application.getAttribute("liuyanjihe");
pageContext对象
pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境.
这个对象不仅封装了对其它8大隐式对象的引用,
它自身还是一个域对象,可以用来保存数据。
并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。
通过pageContext获得其他对象:
getException方法返回exception隐式对象
getPage方法返回page隐式对象
getRequest方法返回request隐式对象
getResponse方法返回response隐式对象
getServletConfig方法返回config隐式对象
getServletContext方法返回application隐式对象
getSession方法返回session隐式对象
getOut方法返回out隐式对象
pageContext对象的方法
public void setAttribute(java.lang.String name,java.lang.Object value)
public java.lang.Object getAttribute(java.lang.String name)
public void removeAttribute(java.lang.String name)
pageContext对象中还封装了访问其它域的方法
public java.lang.Object getAttribute(java.lang.String name,int scope)
public void setAttribute(java.lang.String name, java.lang.Object value,int scope)
public void removeAttribute(java.lang.String name,int scope)
代表各个域的常量
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
response对象
response对象是HttpServletResponse的实例
常用方法:
setCharacterEncoding(String name)---设置响应页面使用的字符编码
setContentType("text/html; charset=utf-8")---设置(MIME类型)请求头
response.getWriter().append(String content)---向页面输出一段字符串
out对象
out对象的类型是JspWriter, 而response.getWriter()是一个PrintWriter, out对象也可以通过pageContext.getOut()获得, 这两个对象的类型不一样
out.print()可能会抛出异常
PrintWriter.print()不会抛出异常
JspWriter是一个抽象类, PrintWriter是一个继承了Writer的普通类
getWriter()方法可以在页面上输出一串字符, out也是一个输出对象, 两者的区别在于, getWriter()方法的执行结果, 总是优先于out对象, 可以使用out.flush()方法, 强行属性缓冲区的内容, 将out对象的输出结果先输出出来
造成这种现象的原因:
out对象实际上对PrintWriter是有依赖的, 他需要先将需要输出的内容存到response的缓冲区里面, 然后等待jsp页面中的out满足一定条件之后, 才会调用输出的方法把内容直接输出到页面上
而PrintWriter是可以直接输出出来的
转发和重定向(面试98%会问)
response.sendRedirect(String location)---请求重定向
客户端行为, 从本质上讲相当于两次请求, 第一次请求的对象不会被保存, 地址栏的Url地址会改变
request.getRequestDispatcher().forward(request, response)---请求转发
服务器行为, 相当于一次请求, 转发后请求对象会被保存, 地址栏url不会改变
out和response(了解)
在JSP页面中不应该使用response.getWriter()这个流。
out对象是JspWriter类型,它与response.getWriter()返回的PrintWriter都是底层响应流的包装。用来向客户端响应字符数据。
但是,在页面中不应该使用response.getWriter()来响应,而是使用隐藏对象out。因为Tomcat总是会先把response.getWriter()中的数据输出给我响应端,然后才是隐藏对象out输出的数据!这会导致使用response.getWriter()输出的数据出现在<html>之前!
如果想看到错误的结果,可以在JSP中使用response.getWriter(),以及out穿插输出。然后使用HttpWatch来查看响应结果。
config和page(了解)
page对象,它只是表示当前JSP“真身”的当前实例,即this。
config是ServletConfig类型,在JSP中一般不会在web.xml文件中配置,但也是可以配置的!就像是配置Servlet配置一样的方法!
<servlet> <servlet-name>e</servlet-name> <jsp-file>/e.jsp</jsp-file> <init-param> <param-name>test</param-name> <param-value>jsp test value</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>e</servlet-name> <url-pattern>/e.jsp</url-pattern> </servlet-mapping> <%=config.getInitParameter("test")%>
exception
exception对象不是所有页面都可以使用的,只能在错误页中可以使用。