欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA学习第四阶段模块一

程序员文章站 2022-03-23 22:19:22
模块一 Servlet(上)Tomcat服务器默认访问ROOT文件夹下index文件Servlet与前端页面一个Java类一种运行在服务器上的特殊类,可以给浏览器的请求做出响应如何使用Servlet第一步:创建Servlet类继承Servlet类实现HttpServlet接口(推荐)GenericServlet类HttpServlet类重写service方法public class HelloServlet3 extends HttpServlet {...

模块一 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设计模式

本文地址:https://blog.csdn.net/miaoit/article/details/110823614