JAVA学习第四阶段模块一

模块一 Servlet(上)

Tomcat服务器

  • 默认访问ROOT文件夹下index文件

Servlet与前端页面

  • 一个Java类
  • 一种运行在服务器上的特殊类,可以给浏览器的请求做出响应

如何使用Servlet

第一步:创建Servlet类

  • 继承Servlet类
  • 实现HttpServlet接口(推荐)
    • GenericServlet类
      • HttpServlet类
  • 重写service方法
public class HelloServlet3 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("继承HttpServlet的方式创建,以后的开发中推荐该方式");
    }
}

第二步:web.xml中配置Servlet

<?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-name>HelloServlet</servlet-name>
        <!--指定别名对应的Servlet类-->
        <servlet-class>com.lagou.demo02.HelloServlet</servlet-class>
    </servlet>
    <!--与上面别名的映射关系-->
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

HttpServlet类

生命周期
  • 编写构造方法
  • 重写init方法
  • 重写service方法
  • 重写destory方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-stFdvkwk-1607333997251)(C:\Users\miaoxun3\AppData\Roaming\Typora\typora-user-images\image-20201201131246371.png)]

  • 多次请求/hello3,构造方法、init方法只会执行一次,只有service方法会被多次执行
  • 停止服务器时会调用destory方法

GET和POST

1.创建Servlet
@WebServlet(name = "HelloServlet4", urlPatterns = "/hello4")
public class HelloServlet4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("POST请求发送成功");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("GET请求发送成功");
    }
}
2.创建HTML页面
  • 选择GET方式请求
    • 浏览器直接URL访问
    • a标签默认GET方式请求
    • form表单提交默认GET方式请求
  • 选择POST方式请求
    • form表单method属性选择post,提交
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试请求</title>
    </head>
    <body>
        <a href="hello4">测试链接</a>
        <form action="hello4" method="post">
           <button>提交</button>
        </form>
    </body>
</html>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>请求参数的获取</title>
    </head>
    <body>
        <form action="paramsServlet" method="post">
            姓名: <input type="text" name="name"><br>
            年龄: <input type="text" name="age"><br>
            爱好: <input type="checkbox" name="hobby" value="Java">Java
            <input type="checkbox" name="hobby" value="C">C
            <input type="checkbox" name="hobby" value="C++">C++<br>
            <button>提交</button>
        </form>
    </body>
</html>
3.获得请求参数
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    //获取参数
    String name = request.getParameter("name");
    System.out.println("获取到的名字是" + name);
    String age = request.getParameter("age");
    System.out.println("获取到的年龄是" + age);
    String[] hobbies = request.getParameterValues("hobby");
    for (String hobby : hobbies) {
        System.out.println(hobby);
    }
    Enumeration<String> names = request.getParameterNames();
    while (names.hasMoreElements()) {
        String nextElement = names.nextElement();
        System.out.println(nextElement);
    }
    Map<String, String[]> map = request.getParameterMap();
    Set<Map.Entry<String, String[]>> entrySet = map.entrySet();
    for (Map.Entry<String, String[]> entry : entrySet) {
        String key = entry.getKey();
        String[] value = entry.getValue();
        System.out.println(key + "对应的值有" + Arrays.toString(value));
    }
}
4.给客户端响应
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //设置编码方式及文本类型
    response.setContentType("text/html;charset=UTF-8");
    //给客户端发出响应
    String encoding = response.getCharacterEncoding();
    System.out.println(encoding);
    PrintWriter writer = response.getWriter();
    writer.println("已经收到!");
    writer.close();
}

Servlet与JDBC

1.编写前端注册页面

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>注册页面</title>
    </head>
    <body>
        <form action="register" method="post">
            用户名:<input type="text" name="userName"><br>&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"><br>
            <input type="submit" value="注册">
        </form>
    </body>
</html>

2.获取前端输入表单信息

package com.lagou.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(name = "RegisterServlet")
public class RegisterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userName = request.getParameter("userName");
        String password = request.getParameter("password");

        System.out.println("获取到的用户名是:" + userName);
        System.out.println("获取到的密码是:" + password);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3.创建实体类

package com.lagou.model;

import java.io.Serializable;

public class User implements Serializable {

    private static final long serialVersionUID = 8913234752244427793L;
    private int id;
    private String userName;
    private String password;

    public User() {
    }

    public User(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

4.DAO层

package com.lagou.dao;

import com.lagou.model.User;
import com.lagou.util.DbUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class UserDao {

    public int register(User user) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            // 1.获取连接
            connection = DbUtil.getConnection();
            // 2.准备sql语句
            String sql = "insert into t_user values(null, ?, ?)";
            // 3.获取PrepareStatement类型的引用
            preparedStatement = connection.prepareStatement(sql);
            // 4.向问号所占的位置设置数据
            preparedStatement.setString(1, user.getUserName());
            preparedStatement.setString(2, user.getPassword());
            // 5.执行sql语句
            int row = preparedStatement.executeUpdate();
            return row; // 执行成功
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 6.关闭资源
            try {
                DbUtil.closeConnection(connection, preparedStatement);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return 0; // 执行失败
    }
}

重定向与转发

重定向

  • response.sendRedirect()
package com.lagou.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(name = "RedirectServlet",urlPatterns = "/redirect")
public class RedirectServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("接收到了浏览器请求");
        response.sendRedirect("target.html");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

转发

  • 将请求转发给另外一个Servlet
package com.lagou.servlet;

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(name = "TargetServlet", urlPatterns = "/target")
public class TargetServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("target");
        request.setAttribute("key1", "value1");
        request.setCharacterEncoding("utf-8");
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/forward");
        requestDispatcher.forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

区别

  • 重定向可以重定向给外部资源,转发只能转发给内部资源(其他Servlet)
  • 重定向是告诉客户端,让客户端自己去重新请求资源
  • 转发是服务端自己重新请求资源返回给客户端

Servlet线程安全问题

  • java代码
package com.lagou.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;
import java.io.PrintWriter;

@WebServlet(name = "ThreadServlet",urlPatterns = "/thread")
public class ThreadServlet extends HttpServlet {

    private String name;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        name = request.getParameter("name");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        PrintWriter writer = response.getWriter();
        writer.write("<h1>" + name + "</h1>");
        writer.close();
    }

    protected  void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

  • html代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试线程安全</title>
    </head>
    <body>
        <iframe src="thread?name=guanyu" frameborder="0"></iframe>
        <iframe src="thread?name=zhangfei" frameborder="0"></iframe>
        <iframe src="thread?name=liubei" frameborder="0"></iframe>
    </body>
</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zoqXgXYs-1607333997252)(C:\Users\miaoxun3\AppData\Roaming\Typora\typora-user-images\image-20201205101010717.png)]

  • 解决方式
    • 方法加锁
    • name变量修改为局部变量,每次请求重新创建

状态管理

  • 多次交互的数据状态保存
    • 保存在客户端(Cookie)
    • 保存在服务端(Session)

Cookie

  • 客户端首次请求,服务器通过响应将Cookie传递给客户端(响应头)
  • 客户端再次发起请求,带着cookie再次发起请求(请求头)
  • 本地存储Cookie只有一个
生命周期
  • 默认生命周期–>保存在内存中,浏览器关闭Cookie消失
  • 使用setMaxAge(int expiry)设置最大时间,单位/秒
    • expiry = 0 立即删除 存储里看不到
    • expiry < 0 浏览器关闭后失效
    • expiry > 0 在expiry秒后失效
路径
  • setPath() 设置Cookie的路径
  • 访问的请求地址必须符合Cookie的路径或者其子路径时,浏览器才会发送Cookie信息
特点
  • 不适合存储所有数据,只用于存储少量非敏感信息
    • 将数据存储在浏览器不安全
    • 最多存储大约4KB数据
    • 只能保存字符串信息
    • 可以通过浏览器设置为禁止使用

Session

生命周期
  • 为了节省资源,服务器会自动清理空闲时间过长的session对象,默认30分钟
  • setMaxInactiveInterval(int interval) 设置失效时间
  • 修改配置文件
<session-config>
    <!--设置session超时时间为30分钟-->
	<session-timeout>30</session-timeout>
</session-config>

特点
  • 数据比较安全
  • 能够保存的数据类型丰富,而Cookie只能保存字符串
  • 能够保存更多的数据,而Cookie大约保存4KB
  • 数据保存在服务器端会占用服务器的内存空间,如果存储信息过多、用户量过大,会严重影响服务器的性能。

JSP

  • Java Server Pages
  • 示例
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Hello JSP</title>
  </head>
  <body>
  现在的时间是:<%=new Date()%>
  </body>
</html>

语法结构

声明区
  • <%! %>

    • 可以定义全局变量、方法、类
  • <% %>

    • 可以定义局部变量以及放入任何的Java程序代码
  • <%= %>

    • 可以输出一个变量或一个具体内容,但=后面必须是字符串变量或者可以被转换成字符串的表达式
    • 不需要以;结束,只有一行

案例

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>绘制表格</title>
    </head>
    <body>
        <table>
            <tr>
                <td>id</td>
                <td>name</td>
                <td>age</td>
                <td>salary</td>
            </tr>
            <%
                for (int i = 1; i < 6; i++) {
            %>
            <tr>
                <td><%=i%>
                </td>
                <td><%=i%>
                </td>
                <td><%=i%>
                </td>
                <td><%=i%>
                </td>
            </tr>
            <%
                }
            %>
        </table>
    </body>
</html>

注释

  • HTML文件的注释,浏览器可以查看到
  • <%–… …–%> JSP文件的注释,浏览器看不到
  • <%//… …%> Java语言中的单行注释,浏览器看不到
  • <%/… …/%> Java语言中的多行注释,浏览器看不到

指令和动作

  • 指令格式<%@ 指令 属性=“属性值”>
  • 指令的属性可以设置多个
page指令
  • page指令经常用于导包和设置页面
    • import 导入相应的包,惟一允许在同一文档中多次出现的属性
    • contentType 设置Content-Type响应报头,标明即将发送到浏览器的文档类型
    • pageEncoding 设置页面的编码
    • language 指定页面使用的语言
    • session 控制页面是否参与HTTP会话
    • errorPage 处理当前页面中抛出但未被捕获的任何异常
    • isErrorPage 当前页是否可以作为其他页面的错误处理页面
taglib指令
  • taglib指令用来扩展JSP程序的标签元素,引入其他功能的标签库文件
include指令
  • include指令用于引入另一个JSP程序或HTML文件等
    • <%@include fil=“被包含的文件地址”>

内置对象

out内置对象
  • 向客户端(浏览器)输出信息
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>out内置对象使用</title>
    </head>
    <body>
        <%
            out.print("hello world");
            out.println("hello world");
            out.println("<h1>你好</h1>");
            //out.close();
            int bufferSize = out.getBufferSize();
            System.out.println("获得的缓冲区的字节数是" + bufferSize);
            int remaining = out.getRemaining();
            System.out.println("获得的缓冲区已使用的字节数是:" + remaining);
            out.clear();
        %>
    </body>
</html>


request内置对象
  • 一次请求内可以拿到设置的属性
  • 再次请求拿不到
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>request</title>
    </head>
    <body>
        <%
            String serverName = request.getServerName();
            out.println("服务器名称是:" + serverName);
        %>
    </body>
</html>


response内置对象
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <%
            response.addHeader("refresh", "1");

            Date d1 = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = sdf.format(d1);
        %>

        <%= "当前时间为" + format%>
    </body>
</html>

session内置对象
  • 更换浏览器拿不到属性
application内置对象
  • 服务启动中,更换浏览器也可以拿到属性
pageContext内置对象
  • 只有当前页面可以拿到属性
等级

pageContext < request < session < application

MVC设计模式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值