JSP学习笔记

背景

  • 客户端要跟Java通信,只能通过servlet
  • 如果要返回一个html页面,只能在doGet()方法里,只能一行行写write(),很繁琐
  • 为了解决上述问题,有了JSP
  • JSP解译成Java文件后,源码其实也是一行行out.write()

什么是JSP

  • 本质:就是一个servlet(Java也只能处理Servlet)
  • 负责与用户交互,将最终界面呈现给用户
  • 静 —— > 动
  • HTML+CSS+JS+Java的混合文件
  • Java的代码负责数据处理的部分
  • 转换过程:JSP —— Java程序 —— class字节码文件

工作机制

  • 当服务器收到一个后缀是.jsp的请求时,将该请求交给JSP引擎去处理
  • 每一个JSP文件第一次被访问的时候,JSP引擎会把它翻译成一个Servlet文件,再由Web容器来调用Servlet完成响应

嵌入方式

  • 从开发角度看:JSP = HTML 嵌入 Java代码

  • 具体方式:

    • JSP 脚本:执行Java逻辑代码
    <% //Java代码,只能调方法
    	String str = "Hello";
    	System.out.println(str); // 在控制台输出!!
    	System.out.println(test());
    %>
    
    • JSP 声明:定义方法
    <%! //声明Java方法
    	public String test(){
        	return "Hello";
    	}
    %>
    
    • JSP 表达式:把Java对象直接输出到HTML页面上
    <%=str%>
    
  • 代码整合

<%! 
	public String test(){
    	return "Hello";
	}
%>
<% 
	String str = test();
%>
<%=str%>
  • 循环怎么写
<% 
	for(int i=0;i<names.size();i++){
%>
	<tr>
		<td>
			<%=names.get(i)%>
		</td>
		<td>
			<%=ages.get(i)%>
		</td>
	</tr>
<% 
	}
%>
  • 本质:<% %>内的直接转成Java代码,外面的会翻译成Java代码,并调用write()

九个内置对象

  • 内置:不用去调,直接用就好

  • 原理:JSP的代码会被拷贝到service()里面,而service()的对象已经创建好了或传进来了,可以直接用

  • request:表示一次请求,HttpServletRequest

  • response:表示一次响应,HttpServletResponse

  • pageContext:页面上下文【全局对象】,获取页面信息,pageContext

  • session:表示一次会话,保存用户信息,HttpSession

  • application:表示当前web应用【全局对象】,保存所有用户共享信息,ServletContext

  • config:当前JSP对应的Servlet的ServletConfig对象,获取当前Servlet的信息

  • out:像浏览器输出数据,JSPWriter

  • page:当前JSP对应的servlet对象,Servlet

  • exception:表示JSP页面发生的异常,Exception

request常用方法

  • getParameter()【服务器与客户端之间传递】
// 获取客户端传来的参数,通过key取value
// eg.?id=1&name=wq 都是String类,根据需要转
String getParameter(String key); 
// 转型
Integer id = Integer.parseInt(idStr);
Double score = Double.parseDouble(scoreStr);
// 在JSP中使用
<%
	String id = request.getParameter("id");
%>   
<%=id%>
  • void setAttribute(String key,Object value) 通过键值对的形式来保存数据【服务器内部传递】

  • Object getAttribute(String key) 通过key取出value

  • RequestDispatcher getRequestDispatcher(String path) 主要是用该对象的forward()方法转发请求

/* 以下代码写在test1.jsp中 */
// 将数据存入request中
request.setAttribute("number",id);
// 将请求转发给test2.jsp:生成目的地,再出发
request.getRequestDispatcher("test2.jsp").forward(request,response);

/* 以下代码写在test2.jsp中 */
Integer number = (Integer)request.getAttribute("number");

/* 如果请求转发了,做响应的是test2,如果没转,就是test1;同理,最后的目的地是哪,响应的就是哪个对象 */
  • String[] getParameterValues() 解决“如果同时传了多个相同key的参数,只保存第一个”,获取客户端传来的多个同名参数

  • void setCharacterEncoding(String charset) 指定请求的编码,处理中文乱码

HTTP状态码

  • 200:正常
  • 404:资源找不到
  • 400 :请求类型不匹配
  • 500:Java程序抛出异常

response常用方法

  • sendRedirect(String path) 重定向,页面之间的跳转

    • 转发 getRequestDispatcher和重定向sendRedirect的区别:
      • 转发是将同一个请求传给下一个页面;重定向是创一个新请求传给下一个页面,之前的请求结束生命周期
      • 前者拿得到数据,后者拿不到
      • 转发:同一个请求在服务器之间传递,地址栏不变,也叫服务器跳转
      • 重定向:由客户端发送一次新请求来访问跳转后的目标资源,地址栏改变,也叫客户端跳转
      • 如果两个页面之间需要通过request来传值,必须使用转发,不能重定向
  • 应用:用户登录。如果用户名和密码正确,则跳转到首页(转发),并且展示用户名,否则重新回到登陆页面(重定向)

  • login.jsp——登录页面,提交表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
</head>
<body>
    <form action="/login" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
        <input type="reset" value="重置">
    </form>
</body>
</html>
  • LoginServlet.java——处理登录表单(纯Java代码不要写在JSP)
package com.microsoft.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {

    private String myUsername;
    private String myPassword;

    @Override
    public void init(ServletConfig config) throws ServletException {
        // 如果传入参数有myUsername、myPassword,就要this
        myUsername = config.getInitParameter("username");
        myPassword = config.getInitParameter("password");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username.equals(myUsername) && password.equals(myPassword)){
            // 登录成功——转发
            req.setAttribute("username",username);
            req.getRequestDispatcher("welcome.jsp").forward(req,resp);
        }else{
            // 登录失败——重定向
            resp.sendRedirect("fail.jsp");
        }
    }
}
  • welcome.jsp——登录成功页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>welcome</title>
</head>
<body>
    <h1>登录成功!</h1><br>
    <%
        String username = (String) request.getAttribute("username");
    %>
    欢迎回来,<%=username%>
</body>
</html>
  • fail.jsp——登录失败页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>fail</title>
</head>
<body>
    <h1>登录失败!</h1><br>
    <form action="/login" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
        <input type="reset" value="重置">
    </form>
</body>
</html>
  • web.xml 配置用户信息
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.microsoft.servlet.LoginServlet</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>123456</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
  • 存在问题:用户新开一个页面进入welcome.jsp,就变成null对象了(原因request生命周期太短,需要引入session)

Session

  • 用户会话

  • 问题:服务器无法识别每一次HTTP请求的出处(不知道来自哪个终端),它只会接收到一个请求信号,有可能将用户的响应给其他人

  • 会话:客户端和服务器之间发生的一系列连续的请求和响应的过程 ,打开浏览器进行操作到关闭浏览器的过程

  • 会话状态:指服务器和浏览器在会话过程中产生的状态信息,借助于会话状态,服务器能够把属于同一次会话的一系列请求和响应关联起来(SessionID)

  • 属于同一次会话的请求都有一个相同的标识符——SessionID

    • String类型的session.getId()
    • 即使同一终端,浏览器不同,id就会不同
    • 十六进制

session常用方法

  • String getId() 获取SessionID

  • void setMaxInactiveInterval(int interval) 设置session的失效时间(单位:s)

  • int getMaxInactiveInterval() 获取当前session的失效时间

  • void invalidate() 设置session立即失效

【上面三个配合使用,定时,查看,失效】

  • void setAttribute(String key,Object value) 通过键值对的形式来保存数据

    • 没有,添加【增】
    • 有,修改【改】
  • Object getAttribute(String key) 通过key取出value【查】

  • void removeAttribute(String key) 通过key删除value【删】

    • request也有,但不要用,request本身生命周期短,但session不一样
  • 解决上面“用户登录”问题 —— 拓展作用域以及功能完善

  • 更改LoginServlet.java的doPost()部分——都用重定向

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username.equals(myUsername) && password.equals(myPassword)){
            HttpSession session = req.getSession();
            session.setAttribute("username",username);
            // 登录成功——重定向,用session跟转发没半毛钱关系
            resp.sendRedirect("welcome.jsp");
        }else{
            // 登录失败——重定向
            resp.sendRedirect("fail.jsp");
        }
    }
  • 更改welcome.jsp —— 避免未登录直接访问以及session的调试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>welcome</title>
</head>
<body>
    <%
        String username = (String) session.getAttribute("username");
        if (username != null){
    %>
    <h1>登录成功!</h1><br>
    欢迎回来,<%=username%><br>
    <a href="/logout">注销账户</a>
    <%
        }
        else{
    %>
    <h1>宁还没登录呢</h1><br>
    <a href="/login.jsp">登录</a>
    <%
        }
    %>
</body>
</html>
  • 添加类LogoutServlet.java——新增注销功能
package com.microsoft.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // <a>是GET方法
        HttpSession session = req.getSession();
        // 销毁,注销用户
        session.invalidate();
        // 跳转到login页面
        resp.sendRedirect("login.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

Cookie

  • 不是内置对象

  • 本质:一个记录用户信息的文件,保存在浏览器内

  • 第一次访问某网页的HTTP响应,浏览器会给用户cookie

  • 传递过程

    • 请求:客户端 ——> 服务器
    • 响应:服务器 ——> 客户端
  • cookie对象是个键值对

    • 在请求响应的头中:Cookie:key1=value1;key2=value2;key3=value3

Cookie常用方法

  • response.addCookie(cookie) 增加cookie
  • request.getCookies() 拿回来全部cookie
  • cookie.getName() 拿键
  • cookie.getValue() 拿值
  • void setMaxAge(int age) 设置cookie有效时间(单位:s)
    • 默认值是-1,一关就没了

Session和Cookie的区别

  • session:

    • JSP内本身就存在

    • Java提供,在服务器存储用户信息【存在JVM内存中】

    • 保存的数据是Object

    • 生命周期:随着会话的结束而销毁

    • 保存重要信息 eg.账号密码

  • cookie

    • 要自己new一个

    • 浏览器提供,在客户端存储用户信息

    • 保存的数据是String

    • 生命周期:与会话无关,可以长期存在浏览器中,关机也还在

    • 保存不重要信息 eg.视频播放记录

  • 二者的存取

// Session存
session.setAttribute("username",username);
// Session取
String username = (String) session.getAttribute("username");

// Cookie存
response.addCookie(new Cookie(username,"admin"));
// Cookie取
Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies){
    if(cookie.getName().equals("name")){
        out.write("欢迎回来,"+cookie.getValue());
    }
}
  • 二者退出登录
// session
session.invalidate();

// cookie
cookie.setMaxAge(0)

作用域

  • setAttribute()、getAttribute()

  • page作用域:对应的内置对象是pageContext,当前页面有效(没有实际开发意义)

  • request作用域:对应的内置对象是request,在一次请求内有效(再开一个新网页就不行了)

  • session作用域:对应的内置对象是session,在一次会话内有效(多次请求)

  • application作用域:对应的内置对象是application,对整个web应用有效(跨浏览器,跨主机,存在Tomcat里的)

  • 大小比较:page<request<session<application

  • 应用:网站访问量统计【一般会在服务器关闭时,把count存入数据库】

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
    <h1>首页</h1><br>
    <%
        Integer count = (Integer) application.getAttribute("count");
        if(count == null){
            count = 1;
            application.setAttribute("count",count);
        }else{
            count++;
            application.setAttribute("count",count);
        }
    %>
    <p>这是宁第<%=count%>次访问</p><br>
    <a href="login.jsp">还没登录吗?点我</a>
  </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值