JSP本质上就是一个Servlet,JSP主要负责与用户交互,将网页最终的界面呈现给用户,就是 HTML + CSS + JS + Java
当服务器接收到⼀个后缀是 jsp 的请求时,将该请求交给 JSP 引擎去处理,每⼀个 JSP ⻚⾯第⼀次被访问的时候, JSP 引擎会将它翻译成⼀个 Servlet ⽂件,再由 Web 容器调⽤ Servlet 完成响应。
单纯从开发的⻆度看, JSP 就是在 HTML 中嵌⼊ Java 程序
1.用 Servlet 方法实现 JSP
其实就是将JSP代码一行一行输出,然后被网页解析为HTML并显示
2.打开本地编译后的JSP
例如:index_jsp.java 文件
其实JSP就是自动完成了代码的转化
具体的嵌入方式有三种
<% java代码 %>
<%!
声明 Java 方法
%>
<%=
Java变量
%>
直接写变量,后面不用写 分号 ;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
Hello
world
<%!
public String test(){
return "Hello World 002";
}
%>
<%
String str="HelloWorld001";
System.out.println(str);//控制台输出
String str2=test();
System.out.println(str2);
%>
<%=
str2
%>
网页界面:
控制台界面:
因不明原因,多输出了几次,等待后续研究
案例:JSP输出一个表格
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: DELL
Date: 2020/3/23
Time: 21:03
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
<%
List names=new ArrayList<>();
names.add("张三");
names.add("李四");
names.add("王五");
List ages=new ArrayList<>();
ages.add(22);
ages.add(24);
ages.add(25);
%>
<%
for (int i=0;i
<%
}
%>
姓名
年龄
<%=names.get(i)%>
<%=ages.get(i)%>
用 面向对象思想 , 实体类,进一步优化。
User.java
package com.lut.entity;
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
//带参构造
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
index.jsp
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.lut.entity.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
<%
List list=new ArrayList<>();
list.add(new User("张三",21));
list.add(new User("李四",22));
list.add(new User("王五",23));
%>
<%
for (int i=0;i
<%
}
%>
姓名
年龄
<%=list.get(i).getName()%>
<%=list.get(i).getAge()%>
如果用 list.get(i) 方法获得的是对象
内置对象直接使用,不需要去创建,因为将JSP转化为Servlet时,系统已经自动创建好了对象。
一共有9个,但并不是都常用,但需要都了解
request 表示一次请求 由 HttpServletRequest 类产生
response 表示一次响应 HttpServletResponse
pageContext 页面上下文(整体),获取页面信息 PageContext
session 表示一次会话,保存用户信息 HttpSession
application 表示当前Web应用,全局对象,保存所有用户共享信息 ServletContext
config 当前JSP对应的 Servlet 的 ServletConfig 对象,获取当前Servlet信息
out 向浏览器输出数据 jspWrite
page 当前JSP对应的 Servlet 对象 Servlet
exception 表示JSP页面发生的异常 Exception
···
常用的:request,response,session,application,pageContext
···
1、String getParameter(String key) 获取客户端传来的参数
2、 void setAttribute(String key,Object value) 通过键值对的形式保存数据。
3、 Object getAttribute(String key) 通过 key 取出 value。
(2和3 服务器内部之间,多个JSP之间进行数据传递)
(1.getParameter 从浏览器到服务器之间的信息传递)
test01.jsp
<%
String idStr=request.getParameter("id");//地址栏后面加 ?id=123
Integer id=Integer.parseInt(idStr);
id++;
//将数据存入到request中
request.setAttribute("number",id);
//将请求转发给test2.jsp
request.getRequestDispatcher("text2.jsp").forward(request,response);
%>
text01.jsp
<%=id%>
test02.jsp
<%
Integer number=(Integer) request.getAttribute("number");
%>
text02.jsp
<%=number%>
**注:**地址栏仍然为 text01.jsp 但在text01.jsp的内部已经实现跳转到了 text02.jsp
4、 RequestDispatcher getRequestDispatcher(String path) 返回⼀个 RequestDispatcher 对象,该对象的 forward ⽅法⽤于请求转发。
5、 String[] getParameterValues() 获取客户端传来的多个同名参数。
(地址栏输入:?name=tom&name=catt&name=jack)
<%
String[] names=request.getParameterValues("name");
%>
<%=Arrays.toString(names)%>
6、 void setCharacterEncoding(String charset) 指定每个请求的编码。
request.setCharacterEncoding("UTF-8");
1、 sendRedirect(String path) 重定向,⻚⾯之间的跳转。
Test01
<%
request.setAttribute("name","Tom");
//request.getRequestDispatcher("test02.jsp").forward(request,response);
response.sendRedirect("test02.jsp");//用这种方法并不能传递数据
%>
text02.jsp
<%
String name=(String)request.getAttribute("name");
out.write(name);
%>
转发 getRequestDispatcher 和 重定向 sendRedirect 的区别:
转发是将同⼀个请求传给下⼀个⻚⾯,
重定向是创建⼀个新的请求传给下⼀个⻚⾯,之前的请求结束⽣命周期。
转发:同⼀个请求在服务器之间传递,地址栏不变,也叫服务器跳转。
重定向:由客户端发送⼀次新的请求来访问跳转后的⽬标资源,地址栏改变,也叫客户端跳转。
如果两个⻚⾯之间需要通过 request 来传值,则必须使⽤转发,不能使⽤重定向。
**案例:**实现⽤户登录,如果⽤户名和密码正确,则跳转到⾸⻚(转发)并且展示⽤户名,否则重新回到登陆⻚⾯(重定向)。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
String username=request.getParameter("username");
String password=request.getParameter("password");
//假设用户名为 admin 密码为123456
if(username.equals("admin")&& password.equals("123456")){
//登录成功
request.setAttribute("name",username);
request.getRequestDispatcher("welcome.jsp").forward(request,response);
}else{
//登录失败//用转发和重定向都可以
response.sendRedirect("login.jsp");
}
%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Welcome
<%
String name=(String)request.getAttribute("name");
%>
欢迎回来!<%=name%>
最终页面:
主要作用:完成用户会话
服务器⽆法识别每⼀次 HTTP 请求的出处(不知道来⾃于哪个终端),它只会接受到⼀个请求信号,所以就存在⼀个问题(将⽤户的响应发送给其他⼈),必须有⼀种技术来让服务器知道请求来⾃哪,这就是会话技术。
一次会话:就是客户端和服务器之间发⽣的⼀系列连续的请求和响应的过程,打开浏览器进⾏操作到关闭浏览器的过程。
会话状态:指服务器和浏览器在会话过程中产⽣的状态信息,借助于会话状态,服务器能够把属于同⼀次会话的⼀系列请求和响应关联起来。
<%
String sessionId=session.getId();
%>
<%=sessionId%>
不同的浏览器会获得不同的sessionid,每一个浏览器都是一次单独的会话
-谷歌浏览器
-QQ浏览器
即便是相同的浏览器,关闭后重新打开又是不同的sessionid,即是不同的会话
-第二次打开谷歌浏览器
session 常⽤的⽅法:
String getId() 获取 sessionID
void setMaxInactiveInterval(int interval) 设置 session 的失效时间,单位为秒
(短时间内登陆不用重复输入账号密码,7day)
int getMaxInactiveInterval() 获取当前 session 的失效时间
void invalidate() 设置 session ⽴即失效
void setAttribute(String key,Object value) 通过键值对的形式来存储数据
Object getAttribute(String key) 通过键获取对应的数据
void removeAttribute(String key) 通过键删除对应的数据
案例: 实现⽤户登录,如果⽤户名和密码正确,则跳转到首页并且展示⽤户名,否则重新回到登陆。登陆成功后,在浏览器不关闭的情况下,直接访问session会展示用户名(session),实现退出功能,即再次访问主页不会显示用户名。
注: 在上一个同类型案例中,check.jsp 文件中只用到了java代码,却使用的是 .jsp 文件,并不符合开发规范,这次我们使用 servlet 实现核对功能。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/login" method="post">
<table>
<tr>
<td>用户名:td>
<td><input type="text" name="username"/>td>
tr>
<tr>
<td>密码:td>
<td><input type="password" name="password">td>
tr>
<tr>
<td><input type="submit" value="登录">td>
<td><input type="reset" value="重置">td>
tr>
table>
form>
body>
html>
package com.lut.session;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
private String myusername;
private String mypassword;
@Override
public void init(ServletConfig config) throws ServletException {
//XML里面的值
myusername=config.getInitParameter("username");
mypassword=config.getInitParameter("password");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
//在login.jsp 文件中的 标签
注: 在这里,获取正确的用户名和密码的方式是:将用户名和密码初始化为参数,即从XML文件里面获取,用MXL实现映射关系。
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>loginservlet-name>
<servlet-class>com.lut.session.LoginServletservlet-class>
<init-param>
<param-name>usernameparam-name>
<param-value>adminparam-value>
init-param>
<init-param>
<param-name>passwordparam-name>
<param-value>123456param-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>loginservlet-name>
<url-pattern>/loginurl-pattern>
servlet-mapping>
web-app>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h1>Welcomeh1>
欢迎回来<%=session.getAttribute("username")%>
<a href="logout">退出a>
body>
html>
package com.lut.session;
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
//a标签的请求类型是 get ,所以在 doGet 里面实现
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session=req.getSession();
session.invalidate();//立即失效
resp.sendRedirect("login.jsp");//回到登录页面
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
界面显示:
登陆界面
欢迎界面:
存在问题,如果不使用session,登陆成功后,并退出欢迎界面,(不关闭浏览器),再次回到欢迎界面时(手敲地址访问),并不显示用户信息,如下图所示:
使用session进行改进,(旧的代码已经在源代码中注释),主要在LoginServlet.java里面使用session发送信息,在welcome.jsp里面用sesison接受信息。
修改后,登陆成功后,并退出欢迎界面,(不关闭浏览器),再次回到欢迎界面时,成功显示用户信息。点击“退出登录”,或关闭浏览器,再次回到欢迎界面时(手敲地址访问),并不会显示用户信息。
额外补充:
HTTP 请求状态码
200:正常
404:资源找不到
400:请求类型不匹配
500: Java 程序抛出异常
在这里我们仅讨论4个
page、 request、 session、 application
因为它们都具有:setAttribute、 getAttribute 方法
page 作⽤域:对应的内置对象是 pageContext。
request 作⽤域:对应的内置对象是 request。
session 作⽤域:对应的内置对象是 session。
application 作⽤域:对应的内置对象是 application。
范围大小:page < request < session < application
page 只在当前⻚⾯有效。
<body>
<%
pageContext.setAttribute("name","Tom");
%>
<h1>pageContext</h1>
<%
String name=(String) pageContext.getAttribute("name");
out.write(name);
%>
</body>
request 在⼀次请求内有效。
session 在⼀次会话内有效。
application 对应整个 WEB 应⽤的。
只要tomcat不关闭,关闭浏览器,其他浏览器均可访问
当刷新浏览器或更换浏览器访问时,次数会增加
<%
Integer count=(Integer)application.getAttribute("count");
if (count==null){
count=1;
application.setAttribute("count",count);
}else{
count++;
application.setAttribute("count",count);
}
%>
你是当前的第<%=count%>访客。