#JavaWeb
三. Cookie/Session
1.会话
会话:用户打开了一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程,可以称之为会话 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话 一个网站,怎么证明客户端来过了呢 1.服务端,给客户端一个信件,客户端下次访问服务端带上信件就可以了:cookie 2.服务端登记客户端来过了,下次客户端来的时候匹配客户端:session
2.保存会话的两种技术
cookie:
session:
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或数据放在session中
常见场景:网站登录后,下次免登陆
3.Cookie
从请求中拿到cookie信息 服务器响应给客户端cookie
Cookie[] cookies = request.getCookies();
cookie.getName();
cookie.getValue();
new Cookie("lastLoginTime", System.currentTimeMillis()+"");
cookie.setMaxAge(24*60*60);
response.addCookie(cookie);
cookie:一般会保存在本地的用户目录下 appdata;
一个网站cookie,是否存在上限
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器多个cookie,每个站点最多放20个
- cookie大小有限制,大约4kb
- 上限大概为300个
实例:
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
@WebServlet(name = "CookieDemo1", value = "/CookieDemo1")
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
boolean flag=false;
System.out.println("进入CookieDemo1");
request.setCharacterEncoding("utf-16");
response.setCharacterEncoding("utf-16");
PrintWriter out = response.getWriter();
Cookie[] cookies = request.getCookies();
if(cookies !=null && cookies.length>0){
for (Cookie cookie : cookies) {
if ("lastLoginTime".equals(cookie.getName())) {
out.write("上一次访问的时间是:");
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
flag = true;
}
}
if (!flag){
out.println("这是您第一次访问本站");
}
}
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
cookie.setMaxAge(24*60*60);
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "DeleteCookie", value = "/DeleteCookie")
public class DeleteCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
maven配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>javaweb_session</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
</project>
删除cookie
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期时间为0
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
@WebServlet(name = "CookieDemo2", value = "/CookieDemo2")
public class CookieDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-16");
response.setCharacterEncoding("utf-16");
Cookie[] cookies = request.getCookies();
PrintWriter out = response.getWriter();
if(cookies !=null && cookies.length>0){
for (Cookie cookie : cookies) {
if ("name".equals(cookie.getName())) {
out.println(cookie.getValue());
}
}
}
Cookie cookie = new Cookie("name","莫诺蒙");
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
有时需要编码解码
String name = URLEncoder.encode("莫诺蒙", "utf-8");
System.out.println(URLDecoder.decode(name, "utf-8"));
4.Session(重点)
什么是session
- 服务器会给每一个用户(浏览器),创建一个session
- 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
- 用户登录之后,整个网站他都可以访问->保存用户的信息
import com.mnm.pojo.person;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "SessionDemo1", value = "/SessionDemo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-16");
response.setCharacterEncoding("utf-16");
response.setContentType("text/html;charset=utf-16");
HttpSession session = request.getSession();
session.setAttribute("name",new person("莫诺蒙",18));
String id = session.getId();
if(session.isNew()){
response.getWriter().write("session创建成功,ID:"+id);
}else{
response.getWriter().write("session在服务器中存在了,ID为:"+id);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
import com.mnm.pojo.person;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "SessionDemo2", value = "/SessionDemo2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-16");
response.setCharacterEncoding("utf-16");
response.setContentType("text/html;charset=utf-16");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
person person = (person) session.getAttribute("name");
out.println(person.toString());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "DeleteSession", value = "/DeleteSession")
public class DeleteSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.removeAttribute("name");
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
import java.util.Objects;
public class person {
private String name;
private int age;
public person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
person person = (person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
Session和cookie的区别
- cookie是把用户的数据,写给浏览器保存(保存多个)
- session是把用户的数据,写到用户独占的session中,服务器端保存(保存重要信息,减少服务器资源的浪费)
- session对象由服务创建
使用场景:
四.JSP
1.什么是jsp
Java server pages:Java服务器端页面,也和servlet一样,用于开发动态web技术 最大的特点:
区别
- HTML只给用户提供静态数据
- jsp页面中可以嵌套java代码,为用户提供动态数据
2.jsp原理
思路:jsp到底怎么执行的
-
代码层面没有任何问题 -
服务器内部工作 tomcat中有一个work目录; idea中使用Tomcat的会在idea的Tomcat中生产一个Work目录 从控制台消息中找到目录 发现页面你转变成了java程序 浏览器想服务器发送请求,不管访问什么资源,其实都是在访问servlet jsp最终也会被转变成一个java类 jsp本质上就是一个servelt
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)
throws java.io.IOException, jakarta.servlet.ServletException {
判断请求
if (!jakarta.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许
return;
}
}
内置一些对象
final jakarta.servlet.jsp.PageContext pageContext;
jakarta.servlet.http.HttpSession session = null;
final jakarta.servlet.ServletContext application;
final jakarta.servlet.ServletConfig config;
jakarta.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
.HttpServletRequest request
.HttpServletResponse response
输出页面前增加的代码
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
以上的这些对象,我们可以在jsp页面中直接使用
在jsp页面中: 只要是Java代码就会原封不动的输出 如果是HTML代码,就会被转换成
out.write(" <h1>登陆成功</h1>\n");
3.基础语法
任何语言都有自己的语法,Java也有,jsp作为Java技术的一种应用,它拥有一些自己扩充的语法(了解),Java所有语法都支持
JSP表达式:
<%--JSP表达式
用来将程序的输出,输出到客户端
<%= 变量或者表达式%>--%>
<%=new java.util.Date()%>
JSP脚本片段:
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
out.print("<h1>Sum="+sum+"<h1>");
%>
脚本片段的再实现
<%
int x = 10;
out.println(x);
%>
<P>这是一个JSP文档</P>
<%
out.println(x);
%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>Hello<%=i%></h1>
<%
}
%>
jsp声明:
<%!
static {
System.out.println("Loading Servlet");
}
private int globalVar =0;
public void test(){
System.out.println("进入test");
}
%>
jsp声明:会被编译到JSP生成的java的类中,其他的会被生成到jspService方法中 在JSP中,嵌入java代码即可
JSP的注释,不会再客户端显示,HTML会
4.JSP指令
<%@page args…%> <%@include file=“”%> 提取公共页面
<%@page args…%> 实例: index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
</head>
<body>
<%
int i =1/0;
%>
</body>
</html>
500.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--显示标记声明这是一个错误页面--%>
<%@ page isErrorPage="true"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<img src="../img/500.png">
</body>
</html>
404.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--显示标记声明这是一个错误页面--%>
<%@ page isErrorPage="true"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<img src="../img/404.png">
</body>
</html>
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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" metadata-complete="false">
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
</web-app>
<%@include file=“”%> 实例: jsp2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>
</div>
</body>
</html>
header.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>我是Header</h1>
footer.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>我是Footer</h1>
JSP标签
<%--@include 会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>
<h1>---------------------------------</h1>
<%--jsp 标签 拼接页面,本质还是一个--%>
<jsp:include page="common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="common/footer.jsp"/>
两者的区别: @include 变量是共享的 jsp 标签 变量作用域不同,不会共享
5.九大内置对象
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
pageContext.setAttribute("name1","mnm1");
request.setAttribute("name2","mnm2");
session.setAttribute("name3","mnm3");
application.setAttribute("name4","mnm4");
%>
<%
pageContext.getAttribute("name1");
request.getAttribute("name2");
session.getAttribute("name3");
application.getAttribute("name4");
%>
</body>
</html>
PageContext 存东西 Request 存东西 Respsonse 回复 Session 存东西 Application(ServletContext) 存东西 config(ServletConfig) out 输出 page 不用了解 exception 异常
作用域测试: index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
pageContext.setAttribute("name1","mnm1");
request.setAttribute("name2","mnm2");
session.setAttribute("name3","mnm3");
application.setAttribute("name4","mnm4");
%>
<%
String name1 =(String) pageContext.findAttribute("name1");
String name2 =(String) pageContext.findAttribute("name2");
String name3 =(String) pageContext.findAttribute("name3");
String name4 =(String) pageContext.findAttribute("name4");
String name5 =(String) pageContext.findAttribute("name5");
%>
<%--使用el表达式输出--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
</body>
</html>
EL表达式不会报错,使用<%= %>会报错
pageDemo1.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
String name1 =(String) pageContext.findAttribute("name1");
String name2 =(String) pageContext.findAttribute("name2");
String name3 =(String) pageContext.findAttribute("name3");
String name4 =(String) pageContext.findAttribute("name4");
String name5 =(String) pageContext.findAttribute("name5");
%>
<%--使用el表达式输出--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
</body>
</html>
Request:客户端向服务器发送请求,产生的数据用户看完就没用了,比如:新闻 Session:产生的数据,用户用完,一会还有用,比如:购物车 Application:产生的数据,一个用户用完了,其他用户还能用,比如:在线人数
6.jsp标签,jstl标签,el表达式
jsp标签
jsptag.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:forward page="jsptag2.jsp">
<jsp:param name="name" value="莫诺蒙"/>
<jsp:param name="age" value="18"/>
</jsp:forward>
</body>
</html>
jsptag2.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
</head>
<body>
<h1>
这是jsptag2!
<%--取出参数--%>
<br>名字:<%=request.getParameter("name")%>
<br>年龄:<%=request.getParameter("age")%>
</h1>
</body>
</html>
jstl标签
jstl标签库的使用就是为了弥补html标签的不足,它自动以了许多的标签,可以供我们使用,标签的功能和Java代码一样 jstl介绍
核心标签(掌握部分) 格式化标签 MYSQL标签 XML标签
JSTL标签库使用步骤:
- 引入对应的taglib
- 使用其中的方法
- 在tomcat中也需要映入jstl的包,否则会报错:jstl解析错误
EL表达式来实现:
- 获取数据
- 执行运算
- 获取web开发的常用对象
- 调用Java方法
前提: maven配置,及tomcat lib文件夹下的包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>javaweb_jsp2</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
</project>
coreif.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>if测试</h1>
<form action="coreif.jsp" method="get">
<%--EL表达式获取表单中的数据--%>
<input type="text" name="username" value=${param.username}>
<input type="submit" value="登录">
</form>
<%--判断如果提交的用户名是管理员,则登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="管理员欢迎你!"/>
</c:if>
<c:out value="${isAdmin}"/>
</body>
</html>
结果:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:set var="score" value="50"/>
<c:choose>
<c:when test="${score>=90}">
你的成绩为优秀
</c:when>
<c:when test="${score>=80}">
你的成绩为良好
</c:when>
<c:when test="${score>=60}">
你的成绩为一般
</c:when>
<c:when test="${score<60}">
继续努力
</c:when>
</c:choose>
</body>
</html>
corefor.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
ArrayList<String> people = new ArrayList<>();
people.add("张三");
people.add("李四");
people.add("王五");
people.add("赵六");
request.setAttribute("list",people);
%>
<%--var 每次遍历出来的变量
items 要遍历的对象--%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/><br>
</c:forEach>
<c:out value="---------------------------"/><br>
<c:forEach begin="1" end="3" step="2" var="people" items="${list}">
<c:out value="${people}"/><br>
</c:forEach>
</body>
</html>
7.JavaBean
实体类 JavaBean有特定的写法
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段做映射 ORM ORM:对象关系映射
People表
id | name | age | address |
---|
1 | 张三 | 15 | 张家口 | 2 | 李四 | 21 | 北京 | 3 | 王五 | 18 | 崇礼 |
javabean.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.mnm.pojo.People" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
%>
<%--等价于--%>
<jsp:useBean id="People" class="com.mnm.pojo.People" scope="page"/>
<jsp:setProperty name="People" property="id" value="1"/>
<jsp:setProperty name="People" property="name" value="张三"/>
<jsp:setProperty name="People" property="age" value="15"/>
<jsp:setProperty name="People" property="address" value="张家口"/>
id:<jsp:getProperty name="People" property="id"/>
name:<jsp:getProperty name="People" property="name"/>
age:<jsp:getProperty name="People" property="age"/>
address:<jsp:getProperty name="People" property="address"/>
</body>
</html>
package com.mnm.pojo;
public class People {
private int id;
private String name;
private int age;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public People(int id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public People() {
}
@Override
public String toString() {
return "People{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
|