Servlet学习笔记

一、web相关知识

  • c/s软件结构(客户端与服务端)

  • qq、MySQL数据库
  • 特点: (1)游戏界面可以华丽,充分利用硬件资源 (2)在TCP协议之上自行创建一个应用层协议 (3)开发企业会花费大量资源开发维护客户端软件,开发维护成本高
  • B/S软件结构(浏览器与服务端)

    • 基于http(基于请求响应模型)

    • 浏览器没有充分利用显卡硬件资源,界面看上去比较简陋

    • 客户端即为浏览器,所以客户端开发维护成本为0

  • 资源分类

    • 静态资源:不同用户去访问一个静态资源,得到的结果都一样(例html,css,js,png,jpeg),浏览器内置静态资源的解析引擎。

    • 动态资源:不同用户去访问一个动态资源,可能得到的结果不一样(列Servlet,jsp,asp,php)。

二、创建web项目工程

1、点击file--New--project

2、选java Enterprise---web Application---配置好jdk和Tomcat

 

 

3、写项目名称---路径---finish即可完成一个web项目创建

 

4、创建成功

 

三、Servlet的三种应用:

servlet生命周期:

1、装载Servlet(由相应Tomcat来完成)

2、创建Servlet实例对象

3、调用Servlet的init()方法初始化(只调用一次)

4、调用Servlet的service()方法(业务处理)

5、销毁,调用Servlet的destroy()方法(销毁Servlet,平常Tomcat重启或电脑重启)

java web三大主键:

Servlet,过滤器,监听器

1、实现Servlet接口,重写五个方法(原始方式);

Servlet类

package com.shy;
import javax.servlet.*;
import java.io.IOException;
public class Servlet1 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("Servlet初始化了");
    }
​
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
     //工作方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello");
    }
​
    @Override
    public String getServletInfo() {
        return null;
    }
​
    @Override
    public void destroy() {
        System.out.println("Servlet销毁了");
    }
}

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">
<!--    配置项目进入的页面,默认进index.jsp-->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
<!--    配置Servlet-->
    <servlet>
        <!-- 给Servlet取别名-->
        <servlet-name>servlets</servlet-name>
          <!--  全类名-->
        <servlet-class>com.shy.Servlet1</servlet-class>
    </servlet>
    <servlet-mapping>
        <!-- 给Servlet取别名,名字和上面相同-->
        <servlet-name>servlets</servlet-name>
       <!--配置映射路径-->
        <url-pattern>/Servlet1</url-pattern>
    </servlet-mapping>
</web-app>

流程:运行项目--弹出页面后--在页面的访问路径(http://localhost:8080/Servlet_war_exploded/)的后面写类名,回车即可在控制台打印service()方法打印输出的“hello”,说明完成一个Servlet项目的搭建。

2、继承GenericServlet类(封装了Servlet接口):

ServletDay83类,不需要再web.xml文件里面配置

//在web3.0以后引用注解,相当于web.xml里面的关于Servlet的所有配置
@WebServlet("/Ser")//通过/ser名可以调到该类
public class ServletDay83 extends GenericServlet {
    //工作方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("你好!");
    }
}

流程:在当前类运行项目--弹出页面--在页面的访问路径(http://localhost:8080/Servlet_war_exploded/)写“Ser”回车,在控制台看到service()方法打印输出的“你好!”,说明这种方式也能完成一个Servlet项目的搭建。

3、继承HttpServlet类(继承GenericServlet类的方法)常用方法:

ServletDay84类,不需要再web.xml文件里面配置

package com.shy.servlet;
​
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
​
//在web3.0以后引用注解,相当于web.xml里面的关于Servlet的所有配置
@WebServlet("/Ser4")//根据Ser调用该类
public class ServletDay84 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //get或post请求会执行的方法
        System.out.println("我是get请求");
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //post请求执行的方法
        System.out.println("我是post请求");
    }
}

流程:在当前类运行项目--弹出页面--在页面的访问路径(http://localhost:8080/Servlet_war_exploded/)写“Ser4”回车,在控制台看到get()方法打印输出的“我是get请求”(默认get),说明这种方式也能完成一个Servlet项目的搭建。

四、数据交互()

1、前后端数据交互(request请求)

后端类

​
@WebServlet("/ServletDay85")
public class ServletDay85 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决中文乱码
        request.setCharacterEncoding("utf-8");
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //从前端拿去数据,request,response
        //拿取前端数据request.getParameter("username");里面的参数是前端定义的name值
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //System.out.println(username+"=="+password);
        if ("lisi".equals(username)&&"1234".equals(password)){
            //如果不匹配,跳转到suce.jsp页面
            request.getRequestDispatcher("/suce.jsp").forward(request,response);
        }else {
            //request是我们学习的第一个域对象,有一个作用域,可以在这个作用域范围内共享数据。
            //返回给前端数据
            request.setAttribute("ms","密码或账号错误了");
​
            //登录失败回原来页面
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }
    }
}

前端login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style type="text/css">
        input{
            margin: 10px 10px;
​
        }
    </style>
    <script type=""></script>
</head>
<body>
<form action="/ServletDay85" method="post">
    账号:<input name="username" type="text"/><br>
    密码:<input name="password" type="text"/><br>
    <input type="submit" value="提交"/>
</form>
<%--获取后端数据--%>
${requestScope.ms}
</body>
</html>

前端suce.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<div>登录成功</div>
</body>
</html>

2、后端之间数据交互(request请求,Servlet之间转发数据)

储存数据类

​
@WebServlet("/servletDay86")
public class ServletDay86 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决中文乱码
        request.setCharacterEncoding("utf-8");
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //request是我们学习的第一个域对象,有一个作用域,可以在这个作用域范围内共享数据。
            //将数据存储,另一个类通过request.getAttribute("name"),可获取到存储的值
            request.setAttribute("name","老师来了");
            //请求转发到下一个Servlet,先得到转发器(写下个类的请求)
            RequestDispatcher requestDispatcher = request.getRequestDispatcher("/ServletDay87");
            //再进行请求转发
            requestDispatcher.forward(request,response);
        }
}

接受类

​
@WebServlet("/servletDay87")
public class ServletDay87 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决中文乱码
        request.setCharacterEncoding("utf-8");
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //得到域对象里面的数据,接受Servlet86里面的数据
        Object name = request.getAttribute("name");
        //打印
        System.out.println(name);//老师来了
    }
}

3、通配符

​
//6种方式的通配符
//@WebServlet("/ServletDa9")第一种常用方式
//@WebServlet("/ss/ser9")第二种常用方式
//@WebServlet({"/hello","/ser9"})第san种常用方式,哪个路径都可以访问
//@WebServlet("*.do")第4种前面无斜杠,且do的*号可为任意值
//@WebServlet("/")第5种通配所有,优先级低于已有的url,但不能通配.jsp
//@WebServlet("/*")第6种通配所有,优先级低于已有的url,也能通配.jsp
@WebServlet("/servletDa9")
public class ServletDay89 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决中文乱码(get方式不会乱码)
        request.setCharacterEncoding("utf-8");
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //获取请求的url
        String url = request.getRequestURI();
        System.out.println(url);//ServletDa9
        //获取请求的url
        System.out.println("====");
        StringBuffer url1 = request.getRequestURL();
        System.out.println(url1);//http://localhost:8080/ServletDa9
        //获取请求参数 例:http://localhost:8080/ServletDa9?nam=45
        String remoteUser = request.getQueryString();
        System.out.println(remoteUser);//nam=45
    }
    /*200 --成功响应
    404  --资源没找到(自己写的路径错了)
    500  --后端代码出错(你该去看你的日志了)
    405  --前后端请求不一致
    302  --请求转发
    * */
}

4、响应给前端(response)

@WebServlet("/response01")
public class Servlet01 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
​
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //防止后端数据传到前端乱码
        resp.setContentType("text/html;charset=utf-8");
        //得到流对象
        PrintWriter writer = resp.getWriter();
        //使用流传输到页面
        //writer.write("hello");
        //使用中文会出现乱码
        resp.getWriter().write("张三");
    }
}

5、重定向(多次请求多次响应)

@WebServlet("/response02")
public class Servlet02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
​
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置重定向(两次请求两次响应,可以打开外部资源)
        //resp.sendRedirect("/login.jsp");//内部资源也是两次请求两次响应
        resp.sendRedirect("https://www.baidu.com");
    }
}

6、ServletContext(作用域application整个web应用都能获取到)

存储值类

@WebServlet("/context")
public class ServletContext extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
​
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //得到对象里面的数据,第二种得到域对象的方式ServletContext属于整个web应用都能获取到
        javax.servlet.ServletContext ser = req.getServletContext();
        //设置数据值
        ser.setAttribute("name","全web应用都能获取到我");
    }
}

获取值类

@WebServlet("/context1")
public class ServletContext1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
​
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //得到对象里面的数据,第二种得到域对象的方式ServletContext属于整个web应用都能获取到
        Object name = req.getAttribute("name");
        //得到servletContext中设置的值
        Object name1 = req.getServletContext().getAttribute("name");
        System.out.println(name1);
​
    }
}

7、会话技术cookie

(比如登录时记住密码下次登录就有了,还有购物车)

特点;存储值在客户端,只能存储字符,限制大小,不安全,有默认值

存储值类

WebServlet("/servletCookie")
public class ServletCookie extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //cookie 小饼干  会话技术,cookie是我们客户端会话技术
        // (比如登录时记住密码下次登录就有了,还有购物车)
        //特点:存储的东西只能是字符串,大小有限,不安全
        //细节:Tomcat8以上可以存储中文
        //当要输入字符有空格时,cookie要进行加码
        String encode = URLEncoder.encode("123 456", "utf-8");
        Cookie pass = new Cookie("pass", encode);
        Cookie pass2 = new Cookie("name", encode);
        //设置cookie存活时间
        pass.setMaxAge(60);//让cookie存活60秒,0就是删除cookie,负数默认保存
        //将cookie放在响应里面
        response.addCookie(pass);
        response.addCookie(pass2);
    }
}

获取cookie值类

@WebServlet("/servletCookie1")
public class ServletCookie1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取会话值(先执行存储数据的类在执行获取才会得到数据)
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie:cookies){
            String name = cookie.getName();
            String value = cookie.getValue();
            //cookie解码,不解码空格键会变成加号
            String encode = URLDncoder.encode(value, "utf-8");
            System.out.println(name+"-"+encode);
        }
​
    }
}

8、作用域Session(一次会话)

特点:存值在服务端,没有大小限制,相对于cookie安全

存储值类

@WebServlet("/session")
public class Session extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //session,作用域:一次会话
        HttpSession session = request.getSession();
        session.setAttribute("aa","hello");
        session.setAttribute("bb","12345");
    }
}

获取值类

@WebServlet("/session01")
public class Session01 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //session,作用域:一次会话,获取session存储的值
        Object aa = request.getSession().getAttribute("aa");
        Object bb = request.getSession().getAttribute("bb");
        System.out.println(aa);
        System.out.println(bb);
    }
}

9、过滤器(实现filter接口)

方式一:配置web.xml文件

<!--    配置过滤器-->
<!--    <filter>-->
<!--        <filter-name>filter01</filter-name>-->
<!--        <filter-class>com.shy.servlet.filter.Filter01</filter-class>-->
<!--    </filter>-->
<!--    <filter-mapping>-->
<!--        <filter-name>filter01</filter-name>-->
<!--   要过滤的文件路径-->
<!--        <url-pattern>index.jsp</url-pattern>-->
<!--    </filter-mapping>-->

方式二;注解@WebFilter("拦截文件名")

例,只能访问login.jsp和"/login"注解,实现登录过滤效果

过滤类

//注解过滤器,括号里面写拦截的文件名
@WebFilter("/*")//拦截所有文件
public class Filter02 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
​
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //相对特定的资源放行
        //对servletRequest强转
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        //拿到当前请求的URL
        String requestURI = request.getRequestURI();
       //contains是包含的意思,例,requestURI.contains("/login"):有login,loginWork..都能被访问
        //建议使用equals
        if (requestURI.equals("/login.jsp")||requestURI.equals("/login")){
            //对这两个进行放行
            filterChain.doFilter(servletRequest,servletResponse);
        }else {
            //判断它是否登录过(获取登录成功时,存储的Session值)
            Object isLogin = request.getSession().getAttribute("isLogin");
            //判断有值就放行
            if (isLogin!=null){
                //如果设置的域对象不为空,说明他已经登录过
                filterChain.doFilter(servletRequest,servletResponse);
            }else {
                //如果没有登录,重定向到login.jsp
                response.sendRedirect("/login.jsp");
            }
        }
    }
​
    @Override
    public void destroy() {
​
    }
}

登录类

@WebServlet("/login")
public class Login extends HttpServlet {
    private Cookie[] cookies;
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //处理前端传来的数就编译成utf-8格式
        request.setCharacterEncoding("utf-8");
    }
​
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取前端数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if ("lisi".equals(username) && "123456".equals(password)) {
            //使用Session存值放到前端
            HttpSession session = request.getSession();
            session.setAttribute("isLogin","hello");
            //使用重定向
            response.sendRedirect("/index.jsp");
​
        }else {
            //使用Session存值放到前端
            request.getSession().setAttribute("msg","密码或账户错误!");
            //登录失败返回原来页面
            response.sendRedirect("/login.jsp");
            //request.getRequestDispatcher("/login.jsp").forward(request,response);
        }
​
    }
}

jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style type="text/css">
        input{
            margin: 10px 10px;
        }
        div{
            width: 500px;
            margin: 50px auto;
        }
        p{
            font-size: 30px;
            font-weight: bold;
            color: red;
        }
        #d1{
            margin: 0 auto;
        }
    </style>
    <script type=""></script>
</head>
<body>
<div>
    <div id="d1"><p>登&nbsp;录&nbsp;界&nbsp;面</p></div>
    <form action="/login" method="get">
        账号:<input name="username" type="text"/><br>
        密码:<input name="password" type="text"/><br>
        <input type="submit" value="提交"/>
    </form>
    <p><%--获取后端数据--%></p>
</div>
</body>
</html>

五、jsp

jsp的9个内置对象:pageContext,request,session,application

1、jsp,java语法

<%--放在Servlet方法体里面,控制台输出--%>
<%
    System.out.println("可以写java代码!");
    //int i = 3/0;//错误时跳转jspText01页面
     int a = 3/0;
    pageContext.setAttribute("num",a);
    pageContext.setAttribute("nums","哈哈哈哈哈哈");
%>
<%--第二 种脚本 放在方法外  声明变量--%>
<%! int i = 4;%>
<%--下面会输出4在页面上--%>
<%= i %>

2、页面错误跳转

isErrorPage默认为false,isErrorPage的作用是设置当前页面为错误页面,当在B页面设置errorPage="A.jsp" 后,在B页面出现问题后就自动会跳转到当前的错误页面A

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="jspText01.jsp" isELIgnored="false"%>
<%--isELIgnored="false"false表示页面获取域对象值时,会解析成内容,true表示页面不解析成文本内容--%>
<%--引入一个头部标签,相当于一个logo--%>
<%@include file="suce.jsp"%>include
<%--导入一个标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--放在Servlet方法体里面,控制台输出--%>
<%
//错误时跳转jspText01页面
     int a = 3/0;
%>
​
<p></p>
</body>
</html>

jspText01.jsp

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<p>错误页面</p>
</body>
</html>

3、导入logo

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入一个头部标签,相当于一个logo--%>
<%@include file="suce.jsp"%>include
<html>
<head>
    <title>Title</title>
</head>
<body>
​
</body>
</html>

4、导入外部文件

<%@ page import="java.util.ArrayList" %>
<%@ 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>
​
</body>
</html>

5、el表达式

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java"  %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--使用el在jsp页面中显示少量java代码--%>
<%
request.setAttribute("name","hello");
%>
<%--el表达式取值只能从域中取值--%>
<p>${requestScope.name}</p>
<%--从小到大从域中找=name。直到找到为此--%>
<p>${name}</p>
<%--比较运算符  < > >= <= == + - * / % ^--%>
${3>5}
${3==3}
${5>=4}
${4/2}
${4*2}
${4%20}
${4+2}
<%--&&  || --%>
${4>3&&3==3}
</body>
</html>

6、四大作用域和九大内置对象

九大内置对象:包含四大作用域

对象功能
out用于向客户端、浏览器输出数据
request封装来自客户端、浏览器的各种信息
response封装服务器响应信息
exception封装了jsp程序执行过程中发生的异常和错误信息
config封装了应用程序配置信息
page指向了当前jsp程序本身
session用来保存会话信息,也就是说,可以实现在同一用户的不同请求之间共享数据
application代表了当前应用程序的上下文,可以在不同的用户之间共享信息
pageContext提供了对jsp页面所有对象以及命名空间的访问,整个web服务器都可以访问

四大作用域:

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java"  %>
<%@taglib prefix="cs" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--jsp 内置对象 已经帮我们定义好的隐式对象,不用去声明 --%>
<%
pageContext.setAttribute("a","123");
request.setAttribute("b","123354");
session.setAttribute("c","653");
application.setAttribute("d","76453");
%>
<%--获取作用域值--%>
${pageScope.a}
${requestScope.b}
${sessionScope.c}
${applicationScope.d}
</body>
</html>

7、逻辑运算

<%@ page import="java.util.ArrayList" %><%--
  Created by IntelliJ IDEA.
  Date: 2022/8/19
  Time: 13:36
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java"  %>
<%@taglib prefix="cs" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--if标签 test是必要条件 当我们的test的值为true时 执行标签里面的语句
cs:if的cs是和上面的prefix="cs"一样--%>
<cs:if test="${4>3}">
    <h1>成功</h1>
</cs:if>
<%--choose其实他是相当于我们java里面的 switch--%>
<cs:choose>
    <cs:when test="${3>4}">
        hello1
    </cs:when>
    <cs:when test="${3<4}">
        hello2
    </cs:when>
    <cs:otherwise>
        hello3
    </cs:otherwise>
</cs:choose>
<%--foreach 遍历--%>
<%
    ArrayList<String> list = new ArrayList<>();
    list.add("12");
    list.add("13");
    list.add("14");
    list.add("15");
    session.setAttribute("list",list);
%>
<%--step="1":步长--%>
<cs:forEach var="i" begin="0" end="10" step="1">
    第几个${i}
</cs:forEach>
<%--遍历list数组--%>
<cs:forEach var="nes" items="${list}">
    ${nes}
</cs:forEach>
</body>
</html>

六、JSON&&Ajax请求

1、json(数据格式)

简介:json是一种轻量级的数据交换格式,易于阅读和编写。也易于机器解析和生成

前端转json格式

​
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<script>
<%--    json js对象表示法:做数据传输的时候使用的一种方式;
    json直观明了   可以传输很多数据   json!=对象  相当于java对象与toString方法打印出来的内容之间的关系
    所以说json就是一个字符串,是用来表示或者传输我们放入js对象
    js对象的设置方法
    js对象的名字:字符串类型,可以加引号,单双引号都可以,
                 在我们的名符合变量命名规则的时候,可以不用引号、
    js对象的值的名字:
                    字符串类型,必须加引号(单双)
                    数值类型,不用加
                    关键字(true,null...)不加
--%>
    var person1 = {'user':"lisi",'age':12,'isMarried':false}
    var person2 = {"user":"lisi","age":12,"isMarried":false}
    var person3 = {user:"lisi",age:12,isMarried:false}
    //转化为我们的json格式,使用json的内置方法,参数即为我们特转换的js对象
    var s = JSON.stringify(person1);
    var s2 = JSON.stringify(person2);
    var s3 = JSON.stringify(person3);
    console.log(s);
    console.log(s2);
    console.log(s3);
    var js = {username:"hello",
        "age":12,
        money:null,
        "address":{"city":"独山","province":"贵州省"},
        "school":["hello",123,null,true]
    }
    console.log(js);
    //取对应的值,js.对象名
    let age = js.age;
    console.log(age);
    //取 js["键值"]
    let j = js["username"];
    console.log(j)
    //获取js对象中的js对象中的值
    let city = js.address.city;
    console.log(city);
    console.log("====");
    //获取js对象中的数组中的值
    let schoolElement = js.school[2];
    console.log(schoolElement);
    //遍历
    let school = js.school;
    for (var i in school){
        console.log(school[i]);
    }
</script>
</body>
</html>

后端数据转json格式

@WebServlet("/jsons")
public class JacksonDemo extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   req.setCharacterEncoding("utf-8");
   resp.setContentType("text/html:charset=utf-8");
    ArrayList<User> users = new ArrayList<>();
    //创建一个User对象
    User user = new User();
    user.setUsername("葑");
    user.setPassword("1234");
    user.setAge("29");
    user.setSex("男");
    user.setHobby("打球");
    
    User user1 = new User();
    user1.setUsername("神");
    user1.setPassword("12345");
    user1.setAge("290");
    user1.setSex("女");
    user1.setHobby("飞");
    
    User user2 = new User();
    user2.setUsername("旁");
    user2.setPassword("123456");
    user2.setAge("2978");
    user2.setSex("女");
    user2.setHobby("真");
    
    users.add(user);
    users.add(user1);
    users.add(user2);
    //将我们的java对象转换成json格式,new一个ObjectMapper
    ObjectMapper objectMapper = new ObjectMapper();
    //使用writeValueAsString这个方法吧我们放入java对象转换成json格式的字符串
    String string = objectMapper.writeValueAsString(user);
    String string1 = objectMapper.writeValueAsString(users);
    System.out.println(string1);
    System.out.println("==========");
    System.out.println(string);
    //了解方法,将user内容以json格式写到bb文件上
    objectMapper.writeValue(new FileWriter("D:\\2022Java\\JavaProject\\Servlet02\\web\\bb.text"),user);
   }
    //objectMapper也可以将json格式的字符串转换成我们的java类
        User user3 = objectMapper.readValue("{\"username\":\"葑\",\"password\":\"1234\",\"age\":\"29\",\"sex\":\"男\",\"hobby\":\"打球\"}", User.class);
        System.out.println(user3);
}

2、Ajax(异步)

 

例:输入账号和密码后,如果登录成功就弹出“登录成功”,失败就弹出“登录失败”

jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="/js/jquery-3.5.0.js"></script>
</head>
<body>
<script>
function ajaxPost() {
    <%--    根据id拿到值--%>
    var username = $("#username").val();
    var password = $("#password").val();
    console.log(username+password)
​
<%--Ajax请求 格式:$.ajax({})--%>
    $.ajax({
        url:"/jsons1",//将要提交到的路径
        type:"post",//选择提交的路径
        data:{"name":username,"pwd":password},//键值对形式,与js对象格式相同
        dataType:"JSON",//希望服务器返回的数据格式
        //成功返回到浏览器之后虚妄Ajax做点什么事
        success:function (result) {
            //如果登录成功
            if (result.status=="200"){
                alert(result.mess)
            }else {
                //alert(result.mess)
                $("#msg").css("color","red");
                $("#msg").html(result.mess);
​
            }
        }
    })
}
</script>
账户&nbsp;<input id="username" type="text"/><br>
密码&nbsp;<input id="password" type="password"/><br>
<span id="msg"></span><br>
<button οnclick="ajaxPost()">确定</button>
</body>
</html>

pojo类

public class Result {
    //状态码
    private String status;
    //信息
    private String mess;
    //返回浏览器想要的参数
    private Object object;
​
    public Result() {
    }
​
    @Override
    public String toString() {
        return "Result{" +
                "status='" + status + '\'' +
                ", mess='" + mess + '\'' +
                ", object=" + object +
                '}';
    }
​
    public String getStatus() {
        return status;
    }
​
    public void setStatus(String status) {
        this.status = status;
    }
​
    public String getMess() {
        return mess;
    }
​
    public void setMess(String mess) {
        this.mess = mess;
    }
​
    public Object getObject() {
        return object;
    }
​
    public void setObject(Object object) {
        this.object = object;
    }
​
    public Result(String status, String mess, Object object) {
        this.status = status;
        this.mess = mess;
        this.object = object;
    }
}

业务类

@WebServlet("/jsons1")
public class JacksonDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
​
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //获取前端数据
        String name = req.getParameter("name");
        String pwd = req.getParameter("pwd");
        System.out.println(name+"="+pwd);
        //判断
        if ("lisi".equals(name)&&"123456".equals(pwd)){
            //登录成功了
            Result re = new Result("200", "登录成功了", null);
            //将我们的result  java类型转换成json格式返回给前端
            ObjectMapper objectMapper = new ObjectMapper();
            String string = objectMapper.writeValueAsString(re);
            //将转换后的result写到响应中去
            resp.getWriter().write(string);
​
        }else {
            //
            Result re = new Result("500", "登录失败了", null);
            //将我们的result  java类型转换成json格式返回给前端
            ObjectMapper objectMapper = new ObjectMapper();
            String string = objectMapper.writeValueAsString(re);
            //将转换后的result写到响应中去
            resp.getWriter().write(string);
        }
​
    }
}

3、小常识

1)防止不小心删除:做一个确定删除框刷(confirm("确定是否删除")),删除了要刷新整个页面内(添加操作时也可用): location.reload(),刷新跳转到的页面用:parent.location.reload()

function deletes(i) {
    //确认删除框
    var a = confirm("确定是否删除")
        //如果确定就执行删除操作
    if (a){
        $.ajax({
            url: "/user",
            type: "POST",
            data:{"id":i,"method": "delete"},
            dataType: "JSON",
            success:function (result) {
                if (result.status=="200"){
                    console.log(result.mess);
                    alert(result.mess);
                    //刷新整个页面内
                    location.reload()
                }else {
                    alert(result.mess);
                    console.log(result.mess);
                }
            }
        })
    }
}

2)两种传值的方法:

方式一:form表单传值或普通传值,后端可做跳转。

例:表单提交,写访问路径(action="/login"),后端根据name名取值(request.getParameter("username");)后端进行页面跳转(),后端处理好后用作用域将数据共享到前端,前端通过el表达式获取共享的数据

jsp页面

<body>
<div>
    <div id="d1"><p>登&nbsp;录&nbsp;界&nbsp;面</p></div>
    <form action="/login" method="get">
        账号:<input name="username" type="text"/><br>
        密码:<input name="password" type="text"/><br>
        <input type="submit" value="提交"/>
    </form>
    <p><%--获取后端数据--%>${sessionScope.msg}</p>
</div>
</body>

后端

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取前端数据,通过前端的name名取值
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    if ("lisi".equals(username) && "123456".equals(password)) {
        //使用Session存值放到前端
        HttpSession session = request.getSession();
        session.setAttribute("isLogin","hello");
        //使用重定向
        response.sendRedirect("/index.jsp");
​
    }else {
        //requset响应存值,必须用request跳转页面才能获取到request的值
        request.setAttribute("msg","密码或账户错误!");
        //登录失败返回原来页面
        request.getRequestDispatcher("/login.jsp").forward(request,response);
    }
}

方式二:Ajax传值,前端Ajax内部跳转

例:根据id获取值,通过Ajax将值传给后端,后端通过Ajax的data建名取值(req.getParameter("name");),后端得数据处理好后,会将返回的数据进行处理,然后在Ajax内部进行页面跳转( location.href = "http://localhost:8080/index.jsp";)

jsp页面

<body class="login-bg">
<div class="login">
    <div class="message">用户登录</div>
    <div id="darkbannerwrap"></div>
    <hr class="hr15">
<%--action="javaScript:;":表示不指向任何地方--%>
    <form action="javaScript:;" method="post" class="layui-form">
        <input name="username" placeholder="用户名" id="username"  type="text" class="layui-input" >
        <hr class="hr15">
        <input name="password" placeholder="密码" id="password"  type="password" class="layui-input">
        <hr class="hr15">
        <%--<input value="登录" style="width:100%;" type="submit">--%>
        <button id="btn">登录</button>
        <hr class="hr20" >
    </form>
</div>
<script>
    $("#btn").click(function () {
        //获取值
        var name = $("#username").val();
        var pass = $("#password").val();
        if (name != null && pass != null){
            $.ajax({
                url:"/user",//访问路径
                type:"POST",//传输数据方式get和post
                data:{"method": "login","name":name,"pwd":pass},//以键值对的方式将数据传给后端
                dataType:"JSON",//返回的数据格式
                success:function (result) {//对返回的数据进行判断处理,result是一个变量,怎么写都可以,和后端的名字可以不一样,但可以用变量名点内置名
                    if (result.status=="200"){
                        alert(result.mess);
                        //跳转页面
                        location.href = "http://localhost:8080/index.jsp";
                    }else {
                        alert(result.mess);
                        //跳转到原来页面
                        location.href="http://localhost:8080/login.jsp";
                    }
                }
            })
        }
    })
</script>
</body>

后端

//登录,doget方法调用该方法即可用
private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    String name = req.getParameter("name");
    String pwd = req.getParameter("pwd");
    User user = new User();
    user.setUserName(name);
    user.setUserPwd(pwd);
    //创建Service方法
    Result login = userService.login(user);
    Object object = login.getObject();
    //转成json格式返回给前端
    ObjectMapper objectMapper = new ObjectMapper();
    String string = objectMapper.writeValueAsString(login);
    //响应给 前端
    resp.getWriter().write(string);
}

3)前端页面跳转传值(常用于修改,登录,查询详细等);

A.jsp页面

<script>
    function update(userId) {
    //以键值对的形式存值
        localStorage.setItem("userId",userId);
    //显框
        x_admin_show('添加信息','/B.jsp',600,450);
    }
</script>

B.jsp页面

<script>
    $(document).ready(function () {
        //根据key值获取到userId值
        var userId = localStorage.getItem("userId");
    }             
    //处理好后,点击确认
    function btn() {
       alert("成功了")
       var xxx = parent.layer.getFrameIndex(window.name)
       //关闭当前页面
       parent.layer.close(xxx)
       //加parent表示刷新跳转到的窗口
       parent.location.reload()
    }          
 </script>

七、总结

问题解决
如何处理post请求乱码?req.setCharacterEncoding("utf-8"); //建议写在Servlet第一行
如何处理响应乱码(向前端传值)?resp.setContentType("text/html;charset=utf-8");
Servlet的生命周期?1)创建Servlet对象:首次访问时,创建对象。2)Servlet初始化:伴随着对象创建,执行一次init()方法。3)Servlet销毁:服务器停止,调用destroy()方法进行销毁
转发和重定向各自的原理是什么?1)转发:服务器内部完成跳转,地址栏访问的目标不变,一次请求。2)重定向:客服端中完成跳转,地址栏访问的目标改变,两次请求
如何选跳转方式(转发和重定向)?两个Servlet之间如需传递数据时,使用转发。不需要传递数据时,使用重定向
什么是request作用域?1)拥有存储数据空间(键值对存储),作用范围是一次请求有效(一次请求可以多次转发,一旦响应就结束)。2)将数据存储到request后,在请求中的任何位置进行获取。3)可以传递任意数据(基本数据类型,对像,数组,集合,字符串)
request如何存取数据?存:request.setAttribute(“key”,values);//key:String 。取:request.getAttribute(‘’key”);
response如何存取数据?response没有作用域,仅能通过get请求的形式传递文本数据:1)传递数据:通过url的拼接进行数据传递("/servlet/login.jsp?username=hello")。2)取数据:request.getParameter(“username”);
什么是cookie?由服务器向客户端发送,并存储在在用户本地的文本数据,可用于辨别用户身份或进行会话跟踪。注:只能存字符串
cookie的实现原理?1)客户端首次访问服务器时,服务器将cookie以响应的形式发送给客户端。2)客户端接收cookie后存储在本地。3)客户端再次访问服务器时,会将存储在客户端的cookie在请求时发给服务器。
如何创建cookie?Cookie cookie = new Cookie(“key”,“values”)
如何发送cookie到客户端?response.addCookie();
如何获得客户端发回的cookie?Cookie[] cookie = request.getCookie();获取本站发出的所有Cookie,for(Cookie c:cookie){遍历出需要的cookie:c.getKey(),c.getValue()}
什么是Session?又称会话,同一客户端与服务器建立起链接后的多次请求和响应过程
Session的实现原理?1)当客户端首次访问服务器时,会在服务器创建HTTPSession对象,并将Session对象的ID属性值保存在cookie中。2)伴随着响应的产生,将cookie发送到客户端本地存储。3)再次访问时,将带有ID的cookie再次发送给服务器,有服务器通过SessionID辨别用户。
Session生命周期?开始:第一次用到Session的请求产生,则创建Session。结束:1)关闭浏览器。2)Session超时,session.setMaxInactivInterval(seconds);//设置存活时间。3)手工销毁,则失效,session.invadate();
Session作用域?1)拥有存储数据的空间(map键值对存),作用范围是一次会话有效(使用同一浏览器发出的多次请求,均为一次会话,一旦关闭浏览器,则结束)。2)可以将数据存入session后,在一次会话过程中的任何位置进行获取。3)可以传递任何数据类型(基本数据类型,对象,集合,数组,字符串)
Session如何存取数据?存:session.setAttribute(“key”,values);//key:String,values:Object。取:session.getAttribute(”key“);
URL重写解决的什么问题?Cookie被禁用的话,无法保存jsessionID,也就无法找到原有的Session对象。因此,需要使用response.encodeURL(”url“);完成重写,默认拼接jsessionid字符串。
什么是ServletContext?全局对象,拥有作用域,对应一个Tomcat中的web应用,伴随web启动而创建,web停止而销毁。
request,Session,ServletContext作用域的区别?1)HttpServletRequest:一次请求开始,响应之前有效。2)ServletSession:一次会话开始,浏览器不关闭或超时之前都有效。3)ServletContext:服务器启动开始,服务器停止之前有效。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值