javaee 的总结(servlet)

1、配置Tomcat服务器

一、Servlet 2.0

1、书写servlet程序
import javax.servlet.*;
import java.io.IOException;

public class MyServletDemo implements Servlet {
    @Override
    /**
     * Servlet 初始化的时候执行,只会执行一次
     */
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("=======init=======");
    }

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

    @Override
    /**
     * Servlet 请求的时候执行,会执行多次
     */
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("======hello service=====");
    }

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

    @Override
    /**
     * Servlet 关闭的时候执行,会执行一次
     */
    public void destroy() {

    }
}
2、配置WEB-INF下面的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-name>demo1</servlet-name>
        <servlet-class>com.example.demoJJ.servlet.MyServletDemo</servlet-class>
        
        <!--
            指定Servlet的创建时机:
            1. 第一次被访问时,创建。load-on-startup 配置的值为负数。
            2. 在服务器启动时创建。load-on-startup 配置为0或者正数
            3. 默认为负数
        -->
        <load-on-startup>-1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
</web-app>
3、解析

当你在浏览器中输入IP端口的时候,tomcat会对你的url进行解析,此时会有一个/demo1的路由,tomcat会在web.xml 中进行解析,刚好会有一个几个/demo1的路由与之对应。此时找到servlet-name,通过servlet-name会找到全类名的类,此时tomcat通过反射找到方法去执行(Class.forName() 加入字节码,newInstance产生实例)。

4、Servlet的生命周期
  1. 被创建:执行init方法,只会执行一次。
  2. 提供服务:执行service方法,执行多次。
  3. 被销毁:执行destory方法,执行一次。(正常关闭的时候会执行)
5、总结
  1. Servlet是单例的,会存在线程安全问题,所以尽量不要定义成员变量。

一、Servlet 3.0的介绍

1、使用注解配置Servlet

介绍:Servlet3.0是向下兼容的,在Servlet 3.0中支持注解的方式配置应用。当只有urlPatterns的时候可以不写。

package com.example.demoJJ.servlet;

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

@WebServlet(urlPatterns = "/demo2")
public class MySev3 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("servlet 3.0");
    }

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

    @Override
    public void destroy() {

    }
}
2、使用HttpServlet进行进行书写程序
package com.example.demoJJ;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
    private String message;

    public void init() {
        message = "Hello World!";
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html");

        // Hello
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>" + message + "</h1>");
        out.println("</body></html>");
    }

    public void destroy() {
    }
}

三、Request对象的部分知识点

1、请求的转发与编码的设置
request.setCharacterEncoding("UTF-8");  // 设置编码
request.getRequestDispatcher("/demo1").forward(request, response);  // 请求转发
2、设置属性,获取属性【共享数据】
request.setAttribute("name", "erik");
request.getAttribute("name");

四、一个小demo

1、工具类的编写
package com.example.demoLogin.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcUtil {

    private static DataSource ds;

    private static String driver;

    static {
        // 读取配置文件
        InputStream resourceAsStream = JdbcUtil.class.getClassLoader().getResourceAsStream("druid.properties");
        Properties properties = new Properties();
        try {
            properties.load(resourceAsStream);
            driver = properties.getProperty("driverClassName");
            // 导入驱动
            Class.forName(driver);
            // 初始化数据库连接池
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取数据源
     *
     * @return
     */
    public static DataSource getDatasource() {
        return ds;
    }


    /**
     * 获取连接池对象
     *
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

}
2、实体类
package com.example.demoLogin.doman;

/**
 *
 */
public class User {

    private int id;

    private String name;

    private String password;

    public User() {
    }

    public User(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
3、操作类
package com.example.demoLogin.dao;

import com.example.demoLogin.doman.User;
import com.example.demoLogin.util.JdbcUtil;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.SQLException;

public class UserDao {

    /**
     * 获取template
     */
    private JdbcTemplate template = new JdbcTemplate(JdbcUtil.getDatasource());

    /**
     * 获取用户
     *
     * @param loginUser
     * @return
     * @throws SQLException
     */
    public User getUserById(User loginUser) {
        try {
            String name = loginUser.getName();
            String password = loginUser.getPassword();
            String sql = "SELECT * FROM USER WHERE name = ? and password = ?";
            return template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), name, password);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }
}
4、Servlet类
package com.example.demoLogin.servlet;

import com.example.demoLogin.doman.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.IOException;
import java.io.PrintWriter;

@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        // 获取属性
        User user = (User) req.getAttribute("user");
        PrintWriter writer = resp.getWriter();
        writer.write("欢迎:" + user.getName() + "登录成功!");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

package com.example.demoLogin.servlet;

import com.example.demoLogin.dao.UserDao;
import com.example.demoLogin.doman.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.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        // 获取请求参数
        String name = req.getParameter("name");
        String password = req.getParameter("password");
        User user = new User();
        user.setName(name);
        user.setPassword(password);
        System.out.println(user);
        User user1 = new UserDao().getUserById(user);
        if (user1 == null) {
            // 失败
            req.getRequestDispatcher("/failServlet").forward(req, resp);
        } else {
            // 成功
            req.setAttribute("user", user1);
            req.getRequestDispatcher("/successServlet").forward(req, resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

package com.example.demoLogin.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("/failServlet")
public class FailServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        PrintWriter writer = resp.getWriter();
        writer.write("登录失败了");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

5、html展示

<%--
  Created by IntelliJ IDEA.
  User: Erik.Zhou
  Date: 2022/2/17
  Time: 11:36
  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="/demoLogin_war_exploded/login" method="get">
    用户名: <input type="text" name="name" placeholder="输入用户名!">
    密码: <input type="password" name="password" placeholder="输入密码!">
    <button type="submit">登录</button>
</form>
</body>
</html>
6、目录结构
image.png
7、状态码

分类:

  • 1xx:服务器就接收客户消息,但没有接收完成,等待一段时间后,发送1xx状态码。
  • 2xx:成功。代表:200
  • 3xx:重定向。代表:302(重定向)【resp.sendRedirect("路径"); 】。304(访问缓存)
  • 4xx:客户端错误。404(资源或者页面不存在)。405 请求方式和对应的方法不存在。403一般用于鉴权。
  • 5xx:服务端错误。500(服务器内部异常)
8、响应数据
  • 响应头:
    1. content-type // resp.setContentType("text/html;charset=utf-8"); 设置编码
9、重定向和转发的区别:

重定向:

  1. 地址栏发生变化。
  2. 重定向可以访问其他站点(服务器)的资源
  3. 重定向是两次请求。不能使用request对象来共享数据
    转发的特点:
  4. 转发地址栏路径不变
  5. 转发只能访问当前服务器下的资源
  6. 转发是一次请求,能使用request对象来共享数据。
10、简单的验证码的使用:
package com.example.demoLogin.servlet;

import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet(name = "ImgServlet", value = "/ImgServlet")
public class ImgServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        int width = 100;
        int height = 50;
        // 1、创建一个对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 2、美化图片
        Graphics graphics = image.getGraphics();
        graphics.setColor(Color.pink);
        graphics.fillRect(0, 0, width, height);
        graphics.setColor(Color.blue);
        graphics.drawRect(0, 0, width - 1, height - 1);
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        for (int i1 = 0; i1 < 4; i1++) {
            int i = random.nextInt(str.length());
            graphics.drawString(str.charAt(i) + "", width / 5 * i1, height / 2);
        }
        // 画干扰线
        for (int i = 0; i < 10; i++) {
            int x1 = random.nextInt(width);
            int x2 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int y2 = random.nextInt(height);
            graphics.drawLine(x1, y1, x2, y2);
        }
        // 3、将图片保存到页面
        ImageIO.write(image, "jpg", response.getOutputStream());
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
11、资源的处理:[文件下载]
        // 获取参数
        String filename = req.getParameter("filename");
        // 获取预发布
        ServletContext context = req.getServletContext();
        // 获取真实路径
        String realPath = context.getRealPath(filename);
        // 获取输入流对象
        FileInputStream inputStream = new FileInputStream(realPath);
        // 获取类型
        String mimeType = context.getMimeType(filename);
        // 设置response响应头
        // 1、设置响应头类型:content-type
        resp.setHeader("content-type", mimeType);
        resp.setHeader("content-disposition", "attachment;filename=" + filename);
        // 将字节流写到输出流中
        ServletOutputStream outputStream = resp.getOutputStream();
        byte[] bytes = new byte[1024 * 8];
        int len = 0;
        while ((len = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);
        }
        // 关闭流对象
        inputStream.close();
        outputStream.close();
// 可能会初选中文的乱码问题,可以针对不同浏览器设置不同的头信息处理
12、Cookie的快速入门
        // 创建cookie
        Cookie cookie1 = new Cookie("", "");
        cookie1.setMaxAge(100);  // 设置cookie的时间。正数:存活的秒数。0代表删除。默认值为负数,关闭即删除
        // cookie.setPath("/");  // 共享cookie设置cookie 的范围,共享
        // cookie.setDomain(".baidu.com");
        resp.addCookie(cookie1);
        // 获取cookie
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName());
            }
        }
13、Session的快速入门

session存储在服务器端,他的实现是基于cookie的,当第一次请求的时候,服务器端会set-cookie,一个值为:JSESSIONID的对象,后期客户端会通过这个请求头来向后端请求,从而保证了session的一致性。

细节:

  1. 当客户端关闭后,服务器不关闭,再次获取session是否是同一个?
    • 默认情况下不是。
    • 如果需要是同一个则可以创建cookie,键为:JSESSION,设置最大存活时间,让cookie持久化存活。
// 让浏览器关闭后仍然是一个session。
HttpSession session = req.getSession();
Cookie jsessionid = new Cookie("JSESSIONID", session.getId());
jsessionid.setMaxAge(60 * 60);
  1. 客户端不关闭,服务器关闭后,再次获取的session是同一个嘛?【tomcat做了】
    • 不是同一个,但是要群数据不丢失。
    • session 的钝化
      • 在服务器正常关闭之前,将session对象序列号到硬盘上
    • session的活化
      • 在服务器启动后,将session文件转化为内存中的session对象即可。
  2. session什么时候被销毁?
  3. 服务器关闭
  4. session对象调用invalidate()。
  5. session默认的失效时间为 30 分钟。【web.xml中进行配置】
14、JSP的快速入门
  1. 指令:
  • 作用:用户配置JSP页面,导入资源文件
  • 格式:
    <%@ 指令名称 属性名1=属性值 属性名2=属性值2 ....%> 如:<%@ page import="java.net.URLDecoder" %>
  • 分类:
    1. page:配置JSP页面的。<%@ page import="java.net.URLDecoder" %>
    2. include:完成包含。导入页面的资源文件。如:公共头部或者公共尾部
    3. taglib:导入资源。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  1. 注释:<%-- 注释内容 --%>
  2. 在jsp页面中不需要创建,直接使用的对象一共有9个:
变量名 真实类型 作用
pageContext PageContext 当前页面共享数据
request HttpServketRequest 一次请求访问的多个资源
session HTTPSession 一次会话的多个请求间
application ServletContext 所有用户共享的数据
response HttpServletResponse 响应对象
page Object 当前页面的对象
out JSPWrite 输出对象,可以把数据输出到页面上
config ServletConfig Servlet的配置对象
exception Throwable :只有当isErrorPage为true的时候才能使用。
  1. 表达式
<%! %>  // 解析为:类变量
<%= "erik" %> // 输出到页面
<% %> // 局部数据。service中的数据。
15、MVC开发模式
  1. jsp的发展演变历史
    1、早期只有servlet,只能使用response输出标签数据,非常麻烦!
    2、后来有了jsp,简化了servlet的开发,如果过度应用jsp,在jsp中际写大量的java代码,又写大象的html代码,造成难于维护,难于分工协作。
    3、再后来,java的web开发,借鉴mvc开发魔术,是得程序的设计更加的合理。

  2. MVC:

    1. M:Model,模型。完成具体的业务操作,如:查询数据库,封装对象。
    2. V:view,视图。展示数据。
    3. C:controller,控制器。:获取用户的输入,调用模型,传给视图。
  3. 优缺点:

    1. 耦合性低。
    2. 重用性高。
    3. 使得小项目麻烦。
  4. EL表达式

${3>4}
\${3>4} // 忽视el表达式
  1. 使用:
${域名称.域名}:从指定域中获取指定的值
1. pageScope   ---------> pageContext
2. requestScope----------> request
3. sessionScope----------> session
4. applacationScope------>applation(servletContext)
16、过滤器的使用
package com.example.demoLogin;

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

@WebFilter(filterName = "MyFilter", value = {"/*"})
public class MyFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {
    }

    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 放行
        chain.doFilter(request, response);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容

  • 概念 运行在服务器端的小程序 1、用户在访问动态资源,每个用户看到的数据都有可能不一致 2、访问同一个资源,返回的...
    魔笛使者阅读 138评论 0 0
  • 一、Http协议 HTTP协议:超文本传输协议(HTTP,HyperText Transfer Protocol)...
    圣贤与无赖阅读 1,224评论 0 13
  • 0、Servlet基本概念 Servlet是sun提供的一种动态web资源开发技术。本质上就是一段java小程序,...
    ZzzRicardo_Yue阅读 556评论 0 0
  • 搞Java开发不可避免要用到Servlet,知其然知其所以然,它是什么呢?可以看我前面写的1-Java的认识扫盲,...
    多了去的YangXuLei阅读 537评论 0 4
  • 1.概念:运行在服务器端的小程序 Servlet实质是一个接口,定义了JAVA类被浏览器(tomcat识别)的规则...
    Tobebold阅读 149评论 0 1