Javaweb----知识点总结3
今天介绍一些jsp页面。
首先先来强调一点,现在很多人都说jsp过时了。jsp确实过时了,但是这不代表我们在工作中就真的见不到jsp了,你肯定有一些老的项目要维护。何况我们学校这学期还在教这个。不能因噎废食。
我们以后在工作中可能要维护老的项目,就可能遇见jsp页面,看懂的前提就是自己要会。
但是jsp的前后端分离性确实太差了,现在都是后端生成json传给前端,实现了前后端分离。
首先来介绍一下什么是jsp吧,jsp表面上类似于html语言,只不过中间有一些java语言。
其实jsp页面本质上就是servlet程序,浏览器第一次请求jsp页面的时候tomcat服务器会把jsp文件经过编译生成一个java文件,这个java文件里面的程序就是servlet程序。再经过编译生成.class字节码文件交给JVM运行,相应浏览器的需求。
说到底,jsp就是封装了servlet的java程序而已。
jsp长得很像html文件,jsp文件里面有一些特殊的语法:
<%! //极少使用 //声明java代码,作用是可以给jsp翻译出来的java类定义属性和方法,甚至是静态代码块内部类等 %> <%=12//表达式 常用! //表达式脚本 作用是在jsp页面上输出数据 //1. 所有的表达式脚本都会被翻译到_jspService()方法中 //2. 表达式脚本都会被翻译成为out.print()输出到页面上 //3. 由于表达式脚本翻译的内容都在_jspService()方法中,所以_jspService方法中的对象都可以直接使用 //4.表达式脚本中的表达式不能以 ';' 结束 %> <% //代码脚本 //java语句 //作用是可以在JSP页面中编写我们自己的功能 //特点是 /* 1.翻译之后都在_jspService方法中 2.代码脚本由于翻译到_jspService方法中,所以在_jspService方法中的现有对象都可以直接使用 3.还可以由多个代码脚本块组合完成一个完整的java语句 4.代码脚本还可以和表达式脚本一起组合使用,在jsp页面上一起组合使用 */ %> <%--这是jsp注释 可以注释掉jsp页面中所有代码--%>
示例:
<%=12%> 输出整形<br/> <%=12.12%> 输出浮点型<br/> <%="我是字符串"%> 输出字符串<br/>
浏览器:
<%! //定义代码块 static { map = new HashMap<String, Object>(); map.put("key1","value1"); map.put("key2","value2"); map.put("key3","value3"); } %> <%=map%> 输出对象<br/>
浏览器:
但是这种jsp语言太过于麻烦了,尤其体现在html语言和jsp语言的混合使用
比如说我们用for循环写一个表格:
<table border="1" cellspacing="0"> <% for(int j=0;j<10;j++){ %> <tr> <td>第<%=j+1%>行</td> </tr> <% } %> </table>
要混合使用表达式,代码脚本和html语言,这样的代码可读性比较差。
所以要引入EL表达式和JSTL标签,这些我们后面再说。
JSP的九大内置对象:是指tomcat在翻译jsp页面成为Servlet源代码后内部提供的九大对象叫内置对象
request 请求对象
response 响应对象
pageContext jsp上下文对象
session 会话对象
application ServletContext对象
config ServletConfig对象
out jsp输出流对象
page 指向当前jsp的对象
exception 异常对象(需要开启 isErrorPage)
其中的四大域对象:
pageContext(PageContextImpl 类) 当前jsp页面范围内有效
request(HttpServletRequest类) 一次请求内有效
session(HttpSession类) 一个会话范围内有效(会话:打开浏览器,访问服务器,直到关闭浏览器)
application(ServletContext类) 整个web工程范围内都有效
它们的范围从上往下是由小到大的,而四个域在使用的时候,优先顺序分别是:他们从小到大的范围的顺序
pageContext -> request -> session -> application
示例:
scope.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>scope.jsp页面</h1> <% //往四个域中都分别保存了数据 pageContext.setAttribute("key","pageContext"); request.setAttribute("key","requestContext"); session.setAttribute("key","sessionContext"); application.setAttribute("key","applicationContext"); %> pageContext域是否有值:<%=pageContext.getAttribute("key")%> <br/> requestContext域是否有值:<%=request.getAttribute("key")%> <br/> sessionContext域是否有值:<%=session.getAttribute("key")%> <br/> applicationContext域是否有值:<%=application.getAttribute("key")%> <br/> <% request.getRequestDispatcher("/scope2.jsp").forward(request,response); %> </body> </html>
我们首先向四大域对象中保存数据,在请求转发到scope2.jsp页面
scope2.jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>scope2.jsp页面</h1> pageContext域是否有值:<%=pageContext.getAttribute("key")%> <br/> requestContext域是否有值:<%=request.getAttribute("key")%> <br/> sessionContext域是否有值:<%=session.getAttribute("key")%> <br/> applicationContext域是否有值:<%=application.getAttribute("key")%> <br/> </body> </html>
最终页面显示:
我们可以发现pageContext域的值没了,因为pageContext的值只在当前页面内有效。
如果我们再进入这个网址:
http://localhost:8080/demo/scope2.jsp
页面显示:
如果我们关闭浏览器再访问这个页面那么sessionContext的值就也是null了(由于我还要写博客,这里不方便展示了)。
我们关闭web工程那么applicationContext域中肯定就没有值了呀。
response对象和out对象的区别:
这两个对象都可以在客户端打印数据,但是他们的区别就是优先权不同
我们使用out.wirte(内容)的时候,会把数据写入到out缓冲区,我们使用response.getWriter().write(内容)的时候会把数据写入到response缓冲区。
当jsp页面所有的代码执行完成后,会进行如下两个操作:
1. 会执行out.flush()操作,会把out缓冲区中的数据追加写入到response缓冲区末尾 2. 会执行response的刷新操作,把全部数据写给客户端
也就是说无论你是先用out输出,还是用response输出,只要你没有在代码中使用out.flush()方法,那么最后在客户端的数据最先是response输出的内容,而不是你写在前面的out对象输出的内容。
这样就会出现顺序混乱的情况,所以我们如果想在页面输出数据,统一使用Out对象输出,这样就不会产生顺序问题。
这里还要注意一点out.write()和out.print()的区别。
区别就是如果我们想输出数字的话,out.write()会自动把数字转换成对应的ASCII码字符输出,而不是我们想输出的数字。
而out.print()会把我们其中写的内容转换成字符串输出,所以我们就统一使用out.print()来输出。
jsp的内容差不多就是这么多了,我们最后再综合使用一下这些知识点:
servlet程序:
public class Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求的参数 //发sql语句查询学生信息 List<Student> studentList = new ArrayList<Student>(); for(int i =0;i< 10 ; i ++) { int t = i+1; studentList.add(new Student(t,"name"+t,(int)(Math.random()*5-2)+18,"Phone"+t)); } //保存查询到的结果到request域中 req.setAttribute("stuList",studentList); //请求转发到showStudent.jsp req.getRequestDispatcher("/showStudent.jsp").forward(req,resp); } }
jsp页面:
<%@ page import="bean.Student" %> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <style> table{ } td,tr{ border: 1px solid red; } </style> </head> <body> <% List<Student> studentList = (List<Student>) request.getAttribute("stuList"); %> <table style="width: 600px;text-align: center;border: 1px solid red;border-collapse: collapse"> <tr> <td>姓名</td> <td>学号</td> <td>年龄</td> <td>电话</td> </tr> <% for(Student student : studentList) { %> <tr style="border: 1px solid red;"> <% String name = student.getName(); int id = student.getId(); int age = student.getAge(); String phone = student.getPhone(); %> <td><%=name%></td> <td><%=id%></td> <td><%=age%></td> <td><%=phone%></td> <%}%> <tr> </table> </body> </html>
页面显示: