Servlet入门

一,简单使用servlet

1.在游览器输出hello Word

1.创建一个java普通类,实现Servlet类

实现servlet类有三种方法:①实现servlet接口②继承GenericServlet③HttpServlet

package com.hqyj.gwr.servlet;

import javax.servlet.*;
import java.io.IOException;

/*
  servlet :server applet 运行在服务器上面的小程序
  定义了一套服务器能够访问servlet
 */
public class ServletDemo01 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello word");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

 2.配置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">
    <!-- 配置servlet -->
    <servlet>
        <!-- 给servlet去一个别名-->
        <servlet-name>servletDemo01</servlet-name>
        <!-- 全类名-->
        <servlet-class>com.hqyj.gwr.servlet.ServletDemo01</servlet-class>
    </servlet>
    <servlet-mapping>
        <!-- 这个别名要和上面的别名一样-->
        <servlet-name>servletDemo01</servlet-name>
        <!-- 配置映射路劲-->
        <url-pattern>/servletDemo01</url-pattern>
    </servlet-mapping>
</web-app>

3.启动服务器,游览器自动弹出页面,如果没有,则自己手动输入访问路径

点击右上角Edit Configurations

 其中的URL

 游览器输出

 简便方法:使用@WebServlet()注解,就不用配置xml文件

括号里面写自定义路径名以"/"开头

亦或是在setting如下位置设置servlet代码模板之后

在文件右键直接创建servlet文件,即可使用
 

2.在游览器实现简单的逻辑控制

创建登录页面,输入用户名以及密码,判断输入是否正确,正确跳转登录成功页面,失败提示用户名或密码输入错误,重新输入。

1、创建login.jsp文件

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/17
  Time: 13:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/loginServlet" method="post">
   <label for="username">用户名: <input id="username" name="username" type="text"></label><br>
    <label for="password">密码:<input id="password" name="password" type="password"></label><br>
    <button type="submit">提交</button>
</form>
<span style="color: red">${requestScope.msg}</span>

</body>
</html>

其中method取值可以是get和post,区别:

 GET
          * 意味着找服务器拿数据,并不希望修改服务器的状态
          * 传递参数是直接放在请求url中(请求行中)
          * 格式是在请求url末尾以?开始 name1=value1&name2=value2
          * url长度有2k限制,传参不能传递大量的数据(文件)
          * 会浏览器的地址栏中显示传递的参数,相对不安全
          * GET方式没有请求体  
POST 
          * 意味这给服务器放数据,意图希望改变服务器的某些状态
          * 传递参数放在请求体中,参数大小没有限制,用于给服务器上传文件
          * 传递参数相对安全 
          * POST有请求体

推荐使用post

2.创建success.jsp文件

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/17
  Time: 14:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>登录成功!</h1>
</body>
</html>

3.创建servlet文件,从前端拿取数据,并作判断

package com.hqyj.gwr.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 java.io.IOException;

@WebServlet("/loginServlet")
public class LoginServlet 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 {
        //从前端拿取参数 服务器创建了两个对象request,response
        //request对象 request.getParameter();拿取数据,里面的参数名值对中的名字
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //逻辑判断
        if ("zhangsan".equals(username)&&"123456".equals(password)){
            //跳转页面到success.jsp页面
            request.getRequestDispatcher("/success.jsp").forward(request,response);
        }else {

            //request 是学习的第一个域对象,有一个作用域,可以在这个作用域范围内去共享数据
            request.setAttribute("msg","用户名或者密码错误");
            //如果登录失败,跳转到login.jsp
            request.getRequestDispatcher("login.jsp").forward(request,response);
        }
    }
}

二,四个作用域

1.request域

request:指属性在一次请求范围内有效。如果页面从给一个页面跳转到另一个页面,那么该属性就决效了。这里所指的跳转是指客户端跳转,比如客户单击超链接跳转到其他页面或者通过浏览器地址栏浏览其他页面。如果使用服务器端跳转则该属性仍然生效。同理使用request对象的setAttribute()和getAttribute()。

1 request内置对象

使用request对象获取请求消息相关的信息 ,请求方式 http总共有7种请求方式,掌握GET和POST两种方式

在使用过程中get请求发送中文没有乱码,tomcat帮我们处理了,但post请求发送中文有乱码

原因在于发送请求时使用utf-8对中文编码

解码时,读请求体数据的流对象中的缓冲区编码默认使用IOS-8859-1,不一致导致乱码

解决: request.setCharacterEncoding("utf-8"),注意要在获取请求参数之前使用。

1.发送数据

①实现方式

继承HttpServlet (最常用方式)

②设置共享数据

 request.setAttribute("数据名","数据内容");

③获取请求转发器

request.getRequestDispatcher("内部资源地址")

④使用请求转发器做请求转发、是一种服务器内部资源的跳转方式

RequestDispatcher.forward(request, response)

package com.hqyj.gwr.request;

import javax.servlet.RequestDispatcher;
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 java.io.IOException;

@WebServlet("/requestDemo01")
public class RequestDemo01 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 {
        //存储一个域数据
        request.setAttribute("name","ggg");
        //请求转发到下一个servlet,先得到请求转发器
        RequestDispatcher rd = request.getRequestDispatcher("/RequestDemo02");
        //再进行请求转发
        rd.forward(request,response);
    }
}

2.接收数据

request.getAttribute("数据名") 获取共享的数据

package com.hqyj.gwr.request;

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 java.io.IOException;

@WebServlet("/requestDemo02")
public class RequestDemo02 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 {
        //得到域对象里面的数据
        Object attribute = request.getAttribute("name");
        //进行打印
        System.out.println(attribute);

        Object name = request.getServletContext().getAttribute("name");
        System.out.println(name);
    }
}

3.其他常用api方法

 ①获取请求的URI

String requestURI = request.getRequestURI();

②获取请求的URL
StringBuffer requestURL = request.getRequestURL();
③获取queryString
String queryString = request.getQueryString();

package com.hqyj.gwr.request;

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 java.io.IOException;

@WebServlet("/RequestDemo03")
public class RequestDemo03 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 {
       //获取请求的URI
        String requestURI = request.getRequestURI();
        System.out.println(requestURI);// /RequestDemo03
        //获取请求的URL
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURL);
        //获取queryString
        String queryString = request.getQueryString();
        System.out.println(queryString);

        
    }
}

练习:模拟用户登录

创建LoginServlet,获取浏览器的登录请求,自行判断是否登录成功,如果成功,跳转/success.jsp,如果失败,跳转会login.jsp

LoginServlet

package com.hqyj.gwr.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 java.io.IOException;

@WebServlet("/loginServlet")
public class LoginServlet 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 {
        //解决请求中文乱码,post请求发送到服务器会乱码,但是get不会,因为Tomcat服务器帮我们处理了
//        request.setCharacterEncoding("utf-8");
        //从前端拿取参数 服务器创建了两个对象request,response
        //request对象 request.getParameter();拿取数据,里面的参数名值对中的名字
        String username = request.getParameter("username");
        System.out.println(username);
        String password = request.getParameter("password");
        System.out.println(password);
        //逻辑判断
        if ("zhangsan".equals(username)&&"1234".equals(password)){
           request.getSession().setAttribute("isLogin","登录过");
            //跳转页面到success.jsp页面
             request.getRequestDispatcher("/success.jsp").forward(request,response);
        }else {

            //request 是学习的第一个域对象,有一个作用域,可以在这个作用域范围内去共享数据
            request.setAttribute("msg","用户名或者密码错误");

            //如果登录失败,跳转到login.jsp
            request.getRequestDispatcher("login.jsp").forward(request,response);
           
        }
    }
}

login.jsp登录界面

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/17
  Time: 13:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/loginServlet" method="post">
   <label for="username">用户名: <input id="username" name="username" type="text"></label><br>
    <label for="password">密码:<input id="password" name="password" type="password"></label><br>
    <button type="submit">提交</button>
</form>
<span style="color: red">${sessionScope.msg}</span>
</body>
</html>

success.jsp

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/17
  Time: 14:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>登录成功!</h1>
</body>
</html>



2.page域

page:就是设置的属性只能在当前页面有效。通过pageContext的setAttribute()和getAttribute()。

设置共享数据和获取共享数据

3.application域

aplicaton:.指在整个服务器范围,知道服务器停止以后才会关效。同理通过applicaton对象的setltribute()和getstributel).application范围就是保存的属性只要服务器不重启,就能在任意页面中获取,就算重新打开浏览器也是可以获取属性的。

servletContext内置对象

 ServletContext 属于 application域 在我们整个web应用都可以应用

代表整个web应用的一个对象,可以使用它来和web服务器通信

ServletContext的生命周期,就是当我们的服务器关闭时销毁

  1. 它是一个域对象,作用范围为整个web应用,可以使用它来在各个web组件(servlet)中共享数据

    1. void setAttribute("数据名", 数据) 共享数据;

    2. Object getAttribute("数据名") 获取共享的数据;

    3. void removeAttribute("数据名") 删除共享的数据;

    4. application域对象使用比较少,要谨慎

  2. 如何获取

    1. request.getServletContext() ,使用request对象来获取

    2. 在HttpServlet中使用this.getServletContext() 获取

package com.hqyj.gwr.servletContext;

import javax.servlet.ServletContext;
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 java.io.IOException;

@WebServlet("/ServletContextDemo01")
public class ServletContextDemo01 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 {
   

        ServletContext servletContext = request.getServletContext();
        System.out.println("ServletContextDemo01****");
        servletContext.setAttribute("name","ggg");
    }
}

4.session域

session内置对象: 指客户浏览器与服务器一次会话范围内,如果服务器断开连接,那么属性就失效了。是服务端的会话技术,共享数据放在服务端。

在一次会话中多次请求和响应之间共享数据,该共享的数据存放在HttpSession对象中

HttpSession它也是一个域对象 作用范围就是一次会话

session方法

void setAttribute(String name, Object obj) 共享一个数据

Object getAttribute(String name) 获取共享的数据

void removeAttribute(String name) 删除共享的数据

发送共享数据

package com.hqyj.gwr.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("/SessionDemo01")
public class SessionDemo01 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 {
        HttpSession session = request.getSession();
        session.setAttribute("id","11");
    }
}

获取共享数据 

package com.hqyj.gwr.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 java.io.IOException;

@WebServlet("/SessionDemo02")
public class SessionDemo02 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 {
        Object id = request.getSession().getAttribute("id");
        System.out.println(id);
    }
}

session总结:

  • 服务器不重启,浏览器关闭之后再打开,获取到session对象是否是同一个?

    • 结论,不是同一个session对象,默认情况JSESSIONID保存在浏览器内存中,如果想要浏览器关闭之后保持session,可以创建名为JSESSIONID的cookie,值为session.getId(),将该cookie的maxAge设置为一个时间。

    • 我们一般不去设maxAge

  • 浏览器不关闭,服务器重启,前后两次获取的session是否是同一个?

    • 结论,对象不是同一个,但是该对象的数据是一摸一样的。

    • tomcat的机制:钝化/软化,钝化为服务器关闭时将所有的session对象序列化到一个文件中,当服务器重启时,将该文件中的对象反序列化(软化)

  • session对象何时会被销毁?

    • 服务器关闭

      • 默认tomcat服务器有30分钟session失效的功能,浏览器一定时间之内不和服务器交互,session就会失效

    • 配置tomcat服务器session默认不活跃的失效时间

三,其他内置对象

1.response

开发者使用response对象设置响应消息

通过response对象获取输出流对象,两种:字节输出流、字符输出流
ServletOutputStream getOutputStream()
PrintWriter getWriter()
使用流对象的write()方法输出响应信息

使用Reponse对象输出字符数据

* 中文乱码问题。 根源在 对字符的编码和解码不一致
* 使用response.setContentType("text/html;charset=utf-8"); 指定响应体数据的文档类型即编码格式

重定向的简单写法

response.sendRedirect("url")

package com.hqyj.gwr.response;

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 java.io.IOException;

@WebServlet("/ResponseDemo02")
public class ResponseDemo02 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 {
        //设置重定向
//        response.sendRedirect("/login.jsp");
        response.sendRedirect("https://home.firefoxchina.cn/?from=extra_start");
    }
}

2.cookie

客户端会话技术 cookie, 共享数据存放在浏览器中  。

会话: 一次会话包含浏览器与服务器之间的多次请求和响应

一次会话,从浏览器第一次发送请求开始,会话建立,直到其中一方主动断开连接为止,会话结束

会话技术解决的问题:解决多次请求和响应之间共享数据

cookie存储的数据格式:名值对

1.cookie问题

①cookie保存时间多长?

       默认情况下,浏览关闭则cookie信息消失(信息存在浏览器的内存中,如果希望持久保存cookie,可以使用Cookie.setMaxAge(int seconds)设置cookie在浏览器中保存的时间

seconds为负数 默认情况 浏览器不持久存储cookie

seconds为整数 单位秒,浏览器持久保存的时长

seconds为0时,服务器告诉浏览器删除该cookie

②cookie能不能保存多个?

可以,多次调用response.addCookie(cookie)

③cookie能不能存储中文?

tomcat8之后是可以的

tomcat8之前不行,可以在发送cookies之前通过url编码,再获取cookie再使用url解码

如果cookie中有空格这种不合法字符,也需要进行url编码,使用时再url解码

URLEncoder.encode("待编码字符串", "utf-8")

URLDecoder.decode("待解码字符串","utf-8")

④其他的项目能访问当前项目中存储的cookie吗?

浏览器给某服务器发送cookie时会根据path属性发送

默认情况不行,path属性值默认为项目的虚拟目录

可以使用Cookie.setPath(String path), 修改为/即所有项目都可以访问

2.session和cookie区别

cookie 共享数据保存在客户端,个数,大小都有限制,类型只能是字符串,不安全。

session 共享数据保存在服务端,个数,大小都没有限制,类型是任意对象,数据相对安全的。

3.filter过滤器

作用,对多个资源的请求作一些通用操作,登录访问,编码转换,敏感字符过滤

  • 生命周期

    • Filter对象在服务器启动时由web服务器创建,这时调用Filter.init()生命周期方法

    • 服务器运行中,该对象一直存在,一个过滤器只会有一个实例对象(单例的)

    • Filter对象在服务器正常关闭时由web服务器销毁,这时回调用Filter.destroy()生命周期方法

  • 2种配置方式

    • @WebFilter("urlPattern") 注解在我们自定义的Filter类上

    • 配置web.xml

<!-- FilterDemo2的配置-->
 <filter> 
    <filter-name>filterDemo2</filter-name>
    <!-- FilterDemo2的全类名--> 
    <filter-class>com.hqyj.zjc.filter.FilterDemo2</filter-class> 
</filter> 
<!-- 配置FilterDemo2要拦截的url样式-->
<filter-mapping> 
   <filter-name>filterDemo2</filter-name> 
   <url-pattern>/hello.jsp</url-pattern> 
</filter-mapping>
  • 过滤器的url pattern的写法

    • /user/* 拦截具有/user/的所有url

    • *.do 拦截后缀名为.do的所有url

    • /* 拦截项目中任何的url

  • 过滤器的代码执行过程

    • 先访问过滤器

    • 再访问被拦截的资源

    • 执行过滤器中放行后的代码

练习:登录功能实现简单的过滤,只有登录成功才能访问success.jsp页面,不能直接访问

package com.hqyj.gwr.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//拦截所有
@WebFilter("/*")
public class LoginFilter 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;
        //拿到当前请求的URI
        String requestURI = request.getRequestURI();
        if (requestURI.contains("/login.jsp") || requestURI.contains("/loginServlet")) {
            //对着两个对象进行放行
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            //判断是否登陆过
            Object attribute = request.getSession().getAttribute("isLogin");
            if (attribute != null) {
                //如果设置的域对象不为空,就说明登录过
                filterChain.doFilter(servletRequest, servletResponse);

            }else {
                //如果未登录。重定向到login.jsp
                response.sendRedirect("login.jsp");
            }
        }
    }



    @Override
    public void destroy() {

    }
}

总结 :

JSP内置对象和属性列举如下:

1.request对象
     客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。
2.response对象
     response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。
3.session对象
     session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.
4.out对象
     out对象是JspWriter类的实例,是向客户端输出内容常用的对象
5.page对象
     page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例
6.application对象
     application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。
7.exception对象
   exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象
8.pageContext对象
pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
9.config对象
config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)

三,JSP,EL,JSTL 

1.JSP

JSP指令 对JSP页面进行配置,引入一些外部资源

常见指令

errorPage:可以配置一个错误页面,当前页面发生异常时,可以跳转到该错误页面

isErrorPage:配置一个错误页面中,配置为true,可以访问jsp的一个内置对象error错误对象,得到异常信息,便于记录日志

import:在JSP页面导入其他java类

include:指令 引入其他JSP页面

taglib:指令 引入标签库

isELIgnored:指定是否忽略el表达式,是否让其发挥作用,默认为false

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/19
  Time: 13:35
  To change this template use File | Settings | File Templates.
--%>
<%--erroPage 定义我们该页面错误时跳转的页面 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" isELIgnored="false" %>
<%--引入jsp页面 --%>
<%@include file="head.jsp"%>
<%--导入标签库指令  相当于java import指令 --%>
<%@taglib prefix="cq" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--放在service方法体里面 --%>
<%
    System.out.println("hello jsp");
    int i =5;
    pageContext.setAttribute("num",i);
    //jsp的内置对象有  已经帮我们定义好的隐式对象 不用去声明的可以直接拿来用的有9个
//    pageContext
//    request
//    session
//    application
    pageContext.setAttribute("aaa","123");
    request.setAttribute("bbb","456");
    session.setAttribute("ccc","789");
    application.setAttribute("fff","000");
%>
<%--第二种脚本 放在方法外面,声明变量 --%>
<%!
    int x = 3;

%>

<%--第三种脚本 输出脚本 --%>
<%=
    x
%>
${pageScope.num}
${pageScope.aaa}
${requestScope.bbb}
${sessionScope.ccc}
${applicationScope.fff}
</body>
</html>

2.EL表达式

  • 定义: Expression Language 表达式语言 用于简化JSP页面书写

  • 语法: ${ 表达式 }

    • 表达式可以有 变量常量

    • 算术运算符 + - * / (div) % (mod)

    • 比较运算符 > < >= <= == !=

    • 逻辑运算符 &&(and) ||(or) !(not)

    • empty 判空运算符 可以判断对象是否为null,如果是数组或List,还可以用于判断该集合中是否有元素

  • 使用el获取变量的值

    • 只能从el特定的4个内置对象中获取值

      • pageScope page域 pageContext对象中共享的数据

      • requestScope request域 request对象中共享的数据

      • sessionScope session域 session对象中共享的数据

      • applicationScope application域 application对象中共享的数据

    • 用法 ${域名.变量名}

    • 域名可以省,${变量名} el会按照域的由小至大进行查找pageScope->requestScope->sessionScope->applicationScope,找到了为止,找不到就显示空串

  • 使用el获取对象中的属性

    • 用法 {域名.变量名.属性名} 对象的属性名指对象定义中对应的getter方法的方法名去掉get剩下的字符串首字母小写后的字符串

  • 使用el获取数组型(数组、List)中的元素

    • 用法 {域名.变量名[脚标]}

  • 使用el获取Map对象中的key的值

    • 用法

      • {域名.变量名.key} ,key的命名必须符合java语言中变量的命名方式

      • {域名.变量名["key"]}

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/19
  Time: 14:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    request.setAttribute("name","tom");
    session.setAttribute("name","jack");
%>
<%--el表达式取值只能从域中取 --%>
${requestScope.name}
<%--从小到大从域中找到name 直到找到为止--%>
${password}
${name}
<%--比较运算符 < > >= <= == --%>
${3>4}<br>
${3<4}<br>
${3>=4}<br>
${3<=4}<br>
<%--+ - * / % --%>
${3+4}<br>
${3-4}<br>
${3*4}<br>
${3/4}<br>
${3%4}<br>
<%--&& || --%>

</body>
</html>

3.JSTL表达式

JSTL:JavaServer pages Tag Libraty JSP标签库

用处:代替使用JSP脚本,可以用于JSP页面做一些只有java代码能做的逻辑控制

1.使用步骤:

工程中导入jstl.jar包,在WEB-INF下创建一个lib包将其复制到里面

 然后导包

JSP使用jsp指令 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 引入jstl的核心标签库

2.学习三个标签

①if标签

test属性中看值是否为true还是false如果true,显示标签体中内容,false 不显示标签体中的内容

一般if标签得配置el表达式来使用如果想判断else的情况,得再写一个if标签

②choose标签

配合<when>标签来进行条件筛选 使用test属性来指定一个条件,条件成功则显示<when>标签体中的内容, 一般配合el表达式使用 相当于switch语句中的 case:

其他条件使用<otherwise>标签指定 相当于switch语句中的 default:

③forEach标签

用法1 用作循环控制,重复输出标签体中内容

var属性定义循环控制变量 begin属性定义寻遍控制变量的起始值 end属性定义循环控制变量的结束值,step定义每次循环时循环控制变量的增长值。

作用:重复显示标签体中的内容 可以使用el表达式访问循环控制变量 <c:forEach var="i" begin="0" end="10" step="2">

用法2 遍历集合

items属性指定在共享域中的一个集合, var指定遍历该集合时的元素的变量名,在forEach标签体中使用el表达式来访问集合中的元素

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %><%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/19
  Time: 15:14
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="cq" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%-- if标签 test是必要的条件 当我们的test的值为true,就执行标签里面的语句--%>
<%-- 结合el表达式--%>
<cq:if test="${3>4}">
    <h1>成功</h1>
</cq:if>
<%-- choose 相当于java的switch--%>
<cq:choose>
    <cq:when test="${2>4}">
        hello
    </cq:when>
    <cq:when test="${6>4}">
       word
    </cq:when>
    <cq:when test="${6>4}">
        java
    </cq:when>
    <cq:otherwise>
        cc
    </cq:otherwise>
</cq:choose>
<%
    List<Object> list = new ArrayList<>();
    list.add("1111");
    list.add("222");
    list.add("333");
    list.add("444");
    session.setAttribute("list",list);
%>
<%--foreach --%>
<%--<cq:forEach var="i" begin="0" end="10" step="4">
    这是循环的第${i}
</cq:forEach>--%>
<cq:forEach var="one" items="${list}" >
    ${one}
</cq:forEach>
</body>
</html>

四,json和ajax

1.json

①json全称:javaSrcipt Object Notation js对象表示法做数据传输时使用的一种格式
    json优点:直观明了,冗余小,可以传很多数据 **json!=js对象** 相当于java对象对象与                                  toString方法打印出来的内容之间的关系
        所以说json就是一个字符串,是用来表示或传输js对象
    js对象的设置方法:
        js对象的名:字符串类型,可以加引号,单双引号都可以
② js对象的值的命名方式:
       字符串类型:只能是单双引号,不能不加引号
       数字类型:不用加引号
       关键字的类型:true false null 不用加引号
       js对象:{名1:值1,名2:值2}
       js数组: [元素1,元素2,元素3,...]
              元素的类型
              字符串类型:只能是单双引号,不能不加引号
              数字类型:不用加引号
              关键字的类型:true false null 不用加引号
              js对象:{名1:值1,名2:值2}
              js数组: [元素1,元素2,元素3,...]
        js对象与json字符串最大的区别在于:
          JSON与JS对象的格式一样, 但是JSON的字符串中属性名必须加双引号。
  ③ 转化为 json格式,使用json内置的方法,参数即为我们要传递的参数
 

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/22
  Time: 9:16
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<script>
   
    // var person = {"username":"zhangsan","age":15,"isMarried":false}
    // var person = {'username':"zhangsan",'age':15,'isMarried':false}
    // var person = {username:"zhangsan",age:15,isMarried:false}
   
     // var person = {"username":'zhangsan',"age":15,'isMarried':false}
     // var person = {"username":'zhangsan',"age":15,'isMarried':false,money:null}
     var person = {
         "username":'zhangsan',
         "age":15,
         'isMarried':false,
         money:null,
         "address":{"province":"四川省","city":"chengdu"},
         "school":["qinghua","beida","huaqing"]
     }



    /*
    转化为 json格式,使用json内置的方法,参数即为我们要传递的参数
     */
    var personJson = JSON.stringify(person);
    alert(personJson)
</script>
</body>
</html>

④ js对象获取值的方法
    第一种方式  js对象.名  常用
    第二种方式  js对象["键名"] 

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/22
  Time: 10:10
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<script>
    var person = {
        "username":'zhangsan',
        "age":15,
        'isMarried':false,
        money:null,
        "address":{"province":"四川省","city":"chengdu"},
        "school":["qinghua","beida","huaqing"]
    }
    /*


     */
    // var age = person.age;
    // alert(age);
    // var person1 = person["username"];
    // alert(person1);
    // // 特殊情况:获取js对象中的js对象中的值
    // var city = person.address.city;
    // alert(city);
    // // 获取js对象中数组元素的值
    // var str = person.school[1];
    // alert(str);
    //遍历js数组
    var school = ["qinghua","beida","huaqing"];
    /*for (var i = 0; i < school.length; i++){
        alert(school[i]);
    }*/
    //相当于增强for循环
    for (var i in school){
        alert(school[i])
    }
</script>
</body>
</html>

⑤java对象和json之间的转换

package com.hqyj.gwr.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hqyj.gwr.entity.User;

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 java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@WebServlet("/JacksonDemo01")
public class JacksonDemo01 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 {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        List<User> list = new ArrayList<>();
        //创建user对象
        User user1 = new User();
        user1.setUsername("杨老师");
        user1.setPassword("123456");
        user1.setSex("男");
        user1.setAge("18");
        user1.setHobby("washFoot");
        User user2 = new User();
        user2.setUsername("张-三");
        user2.setPassword("123456");
        user2.setSex("男");
        user2.setAge("18");
        user2.setHobby("washFoot");
        User user3 = new User();
        user3.setUsername("李四");
        user3.setPassword("123456");
        user3.setSex("男");
        user3.setAge("18");
        user3.setHobby("washFoot");
        list.add(user1);
        list.add(user2);
        list.add(user3);
        //将java对象转化为json格式,new一个ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        //使用writeValueAsString把java对象转换成json格式的字符串
        String userJson = objectMapper.writeValueAsString(user1);
        System.out.println(userJson);
        //了解的方法
        objectMapper.writeValue(new FileWriter("D:\\HQ\\serverlet\\jackson.text"),user1);
        //ObjectMapper支持将list转换为json数组
        String json = objectMapper.writeValueAsString(list);
        System.out.println(json);
        //也支持转换map
        HashMap<String, Object> map = new HashMap<>();
        map.put("username","zhnagsna");
        map.put("age","34");
        map.put("sex","男");
        String mapJson = objectMapper.writeValueAsString(map);
        System.out.println(mapJson);
        //ObjectMapper也可以将json格式的字符串转换成java类 第一个参数是待转换的json,第二个为想要转换成的java类
        User user = objectMapper.readValue("{\"username\":\"杨老师\",\"password\":\"123456\",\"age\":\"18\",\"sex\":\"男\",\"hobby\":\"washFoot\"}", User.class);
        System.out.println(user);
    }
}

2.ajax

①  ajax请求全称:Asynchronous Javascript And XML(异步JavaScript和XML)

异步和同步:指浏览器和服务器之间的步调一致(同步)或不一致(异步)

同步:浏览器给服务器发出请求之后,必须要等待服务器的响应之后,才能做其他事,在等待的过程中浏览器不能响应用户的操作

异步:浏览器给服务器发出请求之后,无需等待服务器的响应,就可以继续响应用户的操作。 用户体验更高

②AJAX:就是浏览器发送请求并对服务器响应数据做出处理的浏览器侧的一项技术;这项技术只需要和服务器交互一小段数据,来实现页面的局部更新。使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。

③Jquery AJAX 三种用法

  $.ajax() 重点掌握这种

  $.get(url,data[,dataType]) //发送get请求方式的请求

  $.post(url,data[,dataType]) //发送post请求方式的请求

练习:写一个注册的系统
1.当鼠标的焦点(onblur)从用户名输入框离开时,发送ajax的请求,
去判断该用户名是否存在,
如果存在的话,显示此用户名太受欢迎了换一个吧,color:red;
如果不存在的话,显示该用户名可用,color:green
2.用户密码要求,用户名要求
3.连接数据库建表查询

登录界面

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 2022/8/22
  Time: 13:46
  To change this template use File | Settings | File Templates.
--%>
<%@ 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>
用户名:<input id="username" type="text" onblur="ajaxPost()"><br>
<sapn id="msg"></sapn><br>
密码:<input id="password" type="password"><br>
<button  onclick="tijao()">提交</button><br>
<sapn id="ms"></sapn><br>

<script>
 
    function ajaxPost() {
        var username = $("#username").val();
        var pwd = $("#password").val();
     //jquery Ajax 写法$.ajax({})
     $.ajax({
         url:"/AjaxServlet",//将要提交到的路径
         type:"POST",//选择提交参数的方式 get或者post
         data:{"name":username,"password":pwd},//名值对形式。与js对象格式相同
         dataType:"JSON",//希望服务器返回数据的格式  text json
         //成功返回到浏览器之后希望ajax做的事
         success:function (result) {
            if (result.status == "200"){
                //
                $("#msg").css("color","red")
                $("#msg").html(result.mess)
            }else {
                //设置样式
                $("#msg").css("color","green")
                $("#msg").html(result.mess)
            }
         }

     })
    }

    function tijao() {
        var username = $("#username").val();
        var pwd = $("#password").val();
        //jquery Ajax 写法$.ajax({})
        $.ajax({
            url:"/Servlet02",//将要提交到的路径
            type:"POST",//选择提交参数的方式 get或者post
            data:{"name":username,"password":pwd},//名值对形式。与js对象格式相同
            dataType:"JSON",//希望服务器返回数据的格式  text json
            //成功返回到浏览器之后希望ajax做的事
            success:function (result) {
                if (result.status == "500"){
                    $("#ms").css("color","yellow")
                    $("#ms").html(result.mess)
                }else{
                    $("#ms","失败")
                }
            }


        })
    }
</script>
</body>
</html>

 用户名判断界面

package com.hqyj.gwr.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hqyj.gwr.util.JDBCUtil;
import com.hqyj.gwr.vo.Result;

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 java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

@WebServlet("/AjaxServlet")
public class AjaxServlet 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 {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        //连接数据库
        Connection conn = null;
        PreparedStatement pre = null;
        ResultSet set = null;
        ArrayList<Object> username = new ArrayList<>();
        try {
            conn = JDBCUtil.getCon();
            String sql = "select * from us ";
            pre = conn.prepareStatement(sql);
             set= pre.executeQuery();
            while (set.next()) {
                username.add(set.getString("name"));
                if(username.contains(name)){
                    Result result = new Result("500","名字有了",null);
                    ObjectMapper objectMapper = new ObjectMapper();
                    String s = objectMapper.writeValueAsString(result);
                    response.getWriter().write(s);
                }else {
                    Result result = new Result("200","名字可以用",null);
                    ObjectMapper objectMapper = new ObjectMapper();
                    String s = objectMapper.writeValueAsString(result);
                    response.getWriter().write(s);
                }
            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JDBCUtil.closeAll(set,pre,conn);
        }


    }
}

提交注册界面

package com.hqyj.gwr.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hqyj.gwr.util.JDBCUtil;
import com.hqyj.gwr.vo.Result;

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 java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

@WebServlet("/Servlet02")
public class Servlet02 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 {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        response.setContentType("text/plain");
        response.setContentType("application/json");
        String name1 = request.getParameter("name");
        String password1 = request.getParameter("password");
        Connection conn = null;
        PreparedStatement pre = null;
        String sql2 = "insert into us values(null ,?,?)";
        try {
            conn = JDBCUtil.getCon();
            pre = conn.prepareStatement(sql2);
            pre.setString(1,name1);
            pre.setString(2,password1);
            pre.executeUpdate();
            Result result = new Result("500","成功",null);
            ObjectMapper objectMapper = new ObjectMapper();
            String s = objectMapper.writeValueAsString(result);
            response.getWriter().write(s);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        JDBCUtil.closeAll(null,pre,conn);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqq00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值