JavaServlet

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。JavaServlet,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

Servlet基础

1.1.名词解释

  • Web应用、HTTP服务器、Web应用服务器

    Web应用被称为Web Application,通过浏览器访问的应用程序,从而为用户提供相关的服务,例如查询、购物等;淘宝,途牛旅游等提供服务的网站;也包含很多公司内部使用的软件,如oa系统,医院内使用的系统,企业内部业务管理系统等;

  • HTTP服务器:也称为Web服务器,主要功能是提供网上信息浏览服务,例如Apache、Nginx、IIS是比较常用的HTTP服务器;使用浏览器访问Web站点或者Web应用,则必须通过HTTP服务器;

  • Web应用服务器:Web应用服务器能够运行服务器上的应用程序,并将结果返回给客户端浏览器;例如,Tomcat就是一种Web应用服务器;通常情况下,Web应用服务器兼具HTTP服务器的部分功能;

1.2.Tomcat安装使用

  1. 直接解压到本地文件夹

  2. 如何启动,解压文件夹 下面的 bin/ 目录下 执行startup.bat

    startup.bat
    
  3. 停止tomcat shutdown.bat

  4. 使用浏览器进行访问 http://127.0.0.1:8080

  5. 端口号的更改在conf/server.xml中 修改后需要重启

1.3.请求体和响应体

​ 1.请求

// 请求行
GET http://localhost:8080/server1/index.html 
//以下是请求头
HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36
x-ijt: v5m5qoph3mu1pt6sfo99rqeljt
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9


​ 2.响应

//响应行
HTTP/1.1 200
//响应头
Accept-Ranges: bytes
ETag: W/"143-1612149278066"
Last-Modified: Mon, 01 Feb 2021 03:14:38 GMT
Content-Type: text/html
Content-Length: 143
Date: Mon, 01 Feb 2021 07:05:08 GMT

//响应体,响应体和响应头之间有空行
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
hello world
</body>
</html>

1.4.Servlet

  • Servlet是JavaEE规范中的Web开发组件;

自定义servlet步骤

​ 1.定义一个类去继承HttpServlet,重写doGet和doPost方法

public class CustomServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("处理一个get请求");
    }
}

​ 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-name>cus</servlet-name>
        <!-- 类的全路径-->
        <servlet-class>com.qy28.sm.CustomServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>cus</servlet-name>
        <!-- 映射的URL路径 -->
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
</web-app>

​ 3.发请求进行测试

http://localhost:8080/server1/test

​ 4.给servlet配置多个请求路径,CustomServlet可以处理/test和 /a请求

    <servlet>
        <servlet-name>cus</servlet-name>
        <!-- 类的全路径-->
        <servlet-class>com.qy28.sm.CustomServlet</servlet-class>
    </servlet>

<!--    一个servlet类配置多个映射路径 -->
    <servlet-mapping>
        <servlet-name>cus</servlet-name>
        <!-- 映射的URL路径  路径带有正斜杠 aaa-->
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>cus</servlet-name>
        <!-- 映射的URL路径  路径带有正斜杠 aaa-->
        <url-pattern>/a</url-pattern>
    </servlet-mapping>

1.5.状态码

  1. “2XX” 凡是2开头的都是成功 200
  2. “4XX” 都表示客户端问题 ,401 403 404 405
  3. “5XX” 都表示服务的问题,内部出错 , 502:网关错误
  4. “3XX” 资源重定向问题

1.6.servlet生命周期

  • servlet会经历几个时期,构造了(构造方法)=》初始化了(init方法)-》提供服务(service方法)=》销毁了(destroy方法)
  • 默认情况下,是在第一次访问的时候 执行构造和初始化并且这两个方法只会执行一次
  • 每次请求的时候会访问service方法
  • 应用卸载或者tomcat关闭的时候执行destroy方法
public class CustomServlet extends HttpServlet {
    public CustomServlet() {
        System.out.println("构造方法调用了");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("servlet初始化了");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("接受所有类型请求的");
    }

    @Override
    public void destroy() {
        System.out.println("servlet 被销毁了");
    }
}

1.7.登录案例

  1. 登录页面
<body>

<form action="/server1/auth">
    user: <input type="text" name="username"> <br>
    pass: <input type="password" name="password"> <br>
    <input type="submit" value="提交">
</form>

</body>
  1. servlet代码
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("收到请求了");
        String user = req.getParameter("username");
        String pass = req.getParameter("password");
        System.out.println(user + " : " + pass);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}
  1. web.xml配置 LoginServlet
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.qy28.sm.LoginServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/auth</url-pattern>
    </servlet-mapping>

Servlet进阶

1.1.Get和Post的区别

  1. Get用于向服务器获取资源信息,Post常用于向服务器提交数据
  2. Get的参数拼接在URL路径中(使用与URL路径隔开,&进行拼接),Post的请求参数在请求体中比Get相对安全
  3. Get的请求数据大小有限制,对URL长度有限制,不能超过2KB,Post默认情况下无限制
    在这里插入图片描述
    在这里插入图片描述

1.2.Servlet的其他配置信息

1.2.1.Servlet初始化参数

  • 是给servlet配置的,其他servlet获取不到

1.web.xml的配置

 <servlet>
        <servlet-name>cus3</servlet-name>
        <servlet-class>com.qy28.sm.CusServlet3</servlet-class>
        <init-param>
            <!--   初始化参数 key:value -->
            <param-name>jdbcUrl</param-name>
            <param-value>jdbc:mysql://localhost:3306</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>cus3</servlet-name>
        <url-pattern>/cus3</url-pattern>
    </servlet-mapping>

2.servlet代码

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get request");
        //获取servlet中的初始化参数
        System.out.println(getInitParameter("jdbcUrl"));
    }

1.2.2.上下文参数

  • 在所有的servlet中都可以获取到

1,web.xml配置

   <!--上下文参数的配置 -->
    <context-param>
        <param-name>para</param-name>
        <param-value>tom</param-value>
    </context-param>

2,sevlet代码

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("收到请求了");
        //获取servlet中的初始化参数
        System.out.println(getInitParameter("jdbcUrl"));
        // 获取上下文 参数
        System.out.println(getServletContext().getInitParameter("para"));
    }

1.2.3.启动加载配置

  • load-on-startup默认是个负数,该servlet会在第一次请求过来的时候进行实例化和初始化,配置为1之后表示在应用部署完成后就进行实例化和初始化

1.web.xml配置

    <servlet>
        <servlet-name>cus3</servlet-name>
        <servlet-class>com.qy28.sm.CusServlet3</servlet-class>
        <init-param>
            <!-- servlet 初始化参数 key:value -->
            <param-name>jdbcUrl</param-name>
            <param-value>jdbc:mysql://localhost:3306</param-value>
        </init-param>
<!--        启动加载 配置  -->
        <load-on-startup>1</load-on-startup>
    </servlet>

1.3. 乱码处理(请求/响应乱码)

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("收到请求了");
        // 请求设置编码格式
        req.setCharacterEncoding("UTF-8");
        //给响应头设置编码格式 数据格式和编码格式
        resp.setContentType("text/html;charset=UTF-8");

        String user = req.getParameter("username");
        String pass = req.getParameter("password");
        System.out.println(user + " : " + pass);

        resp.getWriter().write("<h1>hello你好</h1>");
    }       

1.4.使用注解配置servlet

XML: 松耦合配置

注解:强耦合 ,但是更简洁

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
 	//配置servlet名字
    String name() default "";
	// value()和urlPatterns()是等价的,都是路径配置
    String[] value() default {};
    String[] urlPatterns() default {};
	//配置启动加载参数
    int loadOnStartup() default -1;
	// 配置初始化参数
    WebInitParam[] initParams() default {};

    boolean asyncSupported() default false;

    String smallIcon() default "";

    String largeIcon() default "";

    String description() default "";

    String displayName() default "";
}

servlet代码

@WebServlet(name = "LoginServlet", value = {"/auth", "/auth2"}, loadOnStartup = 1, initParams = {@WebInitParam(name = "jdbc",value ="jdbc:mysql")})
//@WebServlet("/auth")
public class LoginServlet extends HttpServlet {
    public LoginServlet() {
        System.out.println("login构造了");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("收到请求了");
     /*   //获取servlet中的初始化参数
        System.out.println(getInitParameter("jdbcUrl"));
        // 获取上下文 参数
        System.out.println(getServletContext().getInitParameter("para"));*/
        System.out.println(getInitParameter("jdbc"));
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        String user = req.getParameter("username");
        String pass = req.getParameter("password");
        System.out.println(user + " : " + pass);

        resp.getWriter().write("<h1>hello你好</h1>");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

1.5.servlet多线程问题

  • 每个请求过来,tomcat都会有个线程进行处理,本次请求结束后线程任务完成;
  • servlet是单实例的,尽量不要有成员变量,防止多线程间共享成员变量线程安全问题

servlet代码验证

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("收到请求了");
        //当前线程id
        System.out.println(Thread.currentThread().getId());
        //当前线程休眠10秒
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

1.6.域对象

  • 用来存储信息,数据传递

1.request 对象

每次请求都会产生要给request,请求结束后消失

2.session

同一个用户(会话)一个session对象,当浏览器关闭或者session过期,session对象消失

3.ServletContext

整个应用期间只有一个对象,应用部署好就会生成,应用卸载(服务器关闭)消失

1.7.Servlet相关类

1.7.1.ServletContext上下文类

  • 整个应用期间只有一个上下文对象,应用部署好就会生成,应用卸载(服务器关闭)消失

常用的方法

 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取上下文对象
        ServletContext servletContext = getServletContext();
        //获取项目根路径
        System.out.println(servletContext.getContextPath());
        //获取上下文对象中的属性值
        System.out.println(getServletContext().getAttribute("pass"));
        //获取全局初始化参数
        String para = servletContext.getInitParameter("para");
        System.out.println(para);
    }

1.7.2.ServletConfig配置信息类

  • 每个servlet都有一个配置信息类

常用方法

		// 获取配置信息类
		ServletConfig servletConfig = getServletConfig();
        //获取servlet初始化参数
        String initParameter = servletConfig.getInitParameter("");
        // 获取servlet名字
        System.out.println(servletConfig.getServletName());

1.7.3.HttpServletRequest请求

  • 每次请求都会有一个新的请求对象
  • URL统一资源定位符,也就是网址
  • URI统一资源标识符,端口号后面的内容(短的)
1.7.3.1. 常用方法
	 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //请求对象设置字符编码
        req.setCharacterEncoding("UTF-8");
        //URL
        System.out.println(req.getRequestURL());
        //URI
        System.out.println(req.getRequestURI());
        //获取请求方式 get/post
        System.out.println(req.getMethod());
        //指定key获取头信息
        System.out.println(req.getHeader("Host"));
        //获取根路径
        System.out.println(req.getContextPath());
    }
1.7.3.2.请求转发
  • 浏览器发送请求给服务器,服务器内部进行了资源的转发()
  • 特点
    • 浏览器只发了一次请求(请求对象只有一个)浏览器中URL路径不变
    • 可以向域对象中设值,用于数据传递
    • 不能够转到其他应用

servlet1

@WebServlet("/check1")
public class GoodCheckServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //
        System.out.println("check1 完成了");
        //设置域对象属性值
        req.setAttribute("check","1");
        //获取转发对象
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/check2");
        requestDispatcher.forward(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

servlet2

@WebServlet("/check2")
public class GoodCheckServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("check2收到了");
        System.out.println("获取域对象属性值:" + req.getAttribute("check"));
        System.out.println("check2完成了");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
1.7.3.3. “/”在web应用中的使用
  • 如果是浏览器解析,为 http://ip:port
  • 后台服务器解析 http://ip:port/serverPath

1.7.4.HttpServletResponse响应

1.7.4.1.常用方法
 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //字符编码
        resp.setContentType("text/html;charset=UTF-8");
        //设置响应头
        resp.setHeader("Content-Type","text/html;charset=UTF-8");
        // 设置状态码
        resp.setStatus(200);
        req.setAttribute("check2","ok");

        //字节输出流,只能使用其中一个,不能同时用
        resp.getOutputStream().print("hello");
        //字符输出流
        resp.getWriter().write("hello");
    }
1.7.4.2.重定向
  • 浏览器向服务器发送一次请求,服务器返回一个新的地址,浏览器根据新的地址再次发送新的请求
  • 特点
    • 浏览器中URL路径发生改变
    • 请求发送了2次,2个请求对象
    • 可以重定向到其他项目资源
        //重定向
        resp.sendRedirect("/server1/check1");

面试题:转发和重定向的区别

注意点:web-INF是受保护的文件夹,内部的资源通过浏览器无法直接访问

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192942.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!