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>

页面显示:

posted @ 2021-09-20 11:57  Apak陈柏宇  阅读(209)  评论(0编辑  收藏  举报