Servlet简单入门

本文介绍了Servlet的基本概念,包括如何在浏览器中显示Servlet网页,解决中文乱码问题,Servlet的生命周期,以及Servlet API的内容。讲解了在生命周期中类加载、实例化、初始化、服务请求和销毁的操作,并探讨了Servlet与JSP的关系。此外,还阐述了GET和POST方法的区别,以及处理中文乱码的方法。
摘要由CSDN通过智能技术生成

509 Servlet进行动态网页的开发

在这里插入图片描述

Myservlet:

package com.bjsxt.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class Myservlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         PrintWriter out = resp.getWriter();
         out.print("<html>");
         out.print("<head>");
         out.print("</head>");
         out.print("<body>");
         out.print("<h3>This is my first servlet 哈哈</h3>");
         out.print("</body>");
         out.print("</html>");

    }
}
如何把Myservlet写的网页在浏览器中显示?
<?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>a</servlet-name>
        <servlet-class>com.bjsxt.servlet.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>a</servlet-name>
        <url-pattern>/abc</url-pattern>
    </servlet-mapping>
</web-app>
结果中文出现乱码,如何解决?

在这里插入图片描述

加上:服务器响应编码!

resp.setContentType(“text/html;charset=utf-8”);

package com.bjsxt.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.print("<html>");
        out.print("<head>");
        out.print("</head>");
        out.print("<body>");
        out.print("<h3>This is my first servlet 哈哈</h3>");
        out.print("</body>");
        out.print("</html>");

    }
}

使用这种方式开发动态网页!太麻烦了!

510 Servlet进行流程控制

在这里插入图片描述

Login和doLogin的缺点是什么?
  1. 成功应该跳转新的界面!失败返回原来页面!

解决方案: request.getRequestDispatcher(“success.jsp”).forward(request,response);

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>处理登录操作</title>
</head>
<body>
<%--http://localhost:8080/jsp01/doLogin.jsp?uname=2&pwd=4--%>
<%
    //[A]接收Login.jsp传过来的数据

    String u = request.getParameter("uname");
    String p = request.getParameter("pwd");
    //[B]数据处理--拿着用户和密码去数据库作比较
    boolean flag = false;
    if("sxt".equals(u)&&"123".equals(p)){
        flag =true;
    }
    //[C]给用户做出响应
    if(flag){
        //out.print("登陆成功");
        //可以实现页面的跳转--转发
        request.getRequestDispatcher("success.jsp").forward(request,response);
    }else {
        //out.print("登录失败");
        request.getRequestDispatcher("Login.jsp").forward(request,response);
    }
%>
</body>
</html>
  1. JSP本身是负责内容显示的,但是现在却用jsp进行流程控制

如何解决?

package com.bjsxt.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class DoLogin extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //[A]接收Login.jsp传过来的数据

        String u = request.getParameter("uname");
        String p = request.getParameter("pwd");
        //[B]数据处理--拿着用户和密码去数据库作比较
        boolean flag = false;
        if("sxt".equals(u)&&"123".equals(p)){
            flag =true;
        }
        //[C]给用户做出响应
        if(flag){
            //out.print("登陆成功");
            //可以实现页面的跳转--转发
            request.getRequestDispatcher("success.jsp").forward(request,response);
        }else {
            //out.print("登录失败");
            request.getRequestDispatcher("Login.jsp").forward(request,response);
        }
    }
}
<servlet>
    <servlet-name>doLogin</servlet-name>
    <servlet-class>com.bjsxt.servlet.DoLogin</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>doLogin</servlet-name>
    <url-pattern>/doLogin</url-pattern>
</servlet-mapping>

在这里插入图片描述

小节:什么是Servlet

Servlet是一个基于Java技术的动态网页技术,运行在服务器端,由Servlet容器管理,用于生成动态的内容。是JSP的前身

Servlet是平台独立的符合特定规范的java类,编写一个Servlet,实际上就是按照Servlet规范编写一个java类。

Servlet不是由用户或程序员直接调用,而是由容器(Tomcat)管理,没有main()方法。

Servlet和JSP的关系

所有的JSP都要先翻译成Servlet,然后编译成class,最后执行

JSP本质上就是一个Servlet

JSP的执行过程

.jsp—翻译–à.java(Servlet)----编译–.class-----执行—

JSP出现后,Servlet被淘汰了吗?

没有

不再使用Servlet实现动态网页

现在的Servlet用于控制操作

511 Servlet生命周期

1、生命周期

servlet是一个单实例 多线程的程序

​ servlet的生命周期

​ 【1】类加载

​ “com.bjsxt.servlet.LifeServlet”

​ Class clazz= Class.forName(“com.bjsxt.servlet.LifeServlet”);

​ 【2】实例化 (离不开反射)

​ Object obj= clazz.newInstance();

​ 【3】 初始化(离不开反射)

​ 【4】服务请求(service)(离不开反射)

​ 【5】 销毁操作(离不开反射)

类加载的时机

​ 【1】默认的情况是第一次访问servlet的时候进行类加载

​ 【2】0(当启动服务器时候加载) 数字越小加载的时机越往前

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 初始化后调用 init () 方法。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 销毁前调用 destroy() 方法。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

https://www.runoob.com/servlet/servlet-life-cycle.html

下图显示了一个典型的 Servlet 生命周期方案。

  • 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
  • Servlet 容器在调用 service() 方法之前加载 Servlet。
  • 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。

在这里插入图片描述

512 Servlet API的内容

在这里插入图片描述

  1. 为什么非要写service方法?

在这里插入图片描述

web.xml进行配置

<servlet>
    <servlet-name>myServlet2</servlet-name>
    <servlet-class>com.bjsxt.servlet.MyServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet2</servlet-name>
<url-pattern>/MyServlet2</url-pattern>
</servlet-mapping>

直接运行查看结果:

HTTP Status 405 - HTTP method GET is not supported by this URL

在这里插入图片描述

结合源码查找原因:

public interface Servlet {
    //init居然是有参数的!
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();
    //参数是ServletRequest ServletResponse!可以猜测与HttpServletRequest HttpServletResponse

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}

GenericServlet

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

public void init() throws ServletException {
}
    //没有重写
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

HttpServlet

public abstract class HttpServlet extends GenericServlet implements Serializable {

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)res;
        } catch (ClassCastException var6) {
            throw new ServletException("non-HTTP request or response");
        }
		//跳到自己重载的service方法
        this.service(request, response);
    }
}

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //获得提交的方式 get 或者 post
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                //调用自己的doGet
                this.doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获得协议 http协议1.1 https协议。。。
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            //就是上图报的错误!
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

在这里插入图片描述

从源码可知,不重写service方法,会报错!

重写doGet() 和 doPost()也可以!

513 Servlet 读取初始化值和全局参数

问题:编码改变,需要修改所有的servlet中service方法的utf-8—>GBK!

resp.setContentType(“text/html;charset=utf-8”);

参数提取:

package com.bjsxt.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ParamServlet extends HttpServlet {
    String enc ;
    @Override
    public void init() throws ServletException {
        //读取属性文件
        //读取初始化参数
         enc = this.getInitParameter("abc");
        //方式二 相当于只作用一个servlet类
       // enc=this.getServletConfig().getInitParameter("abc");
        System.out.println("初始化参数"+enc);

    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("text/html;charset="+enc);


    }
}
<servlet>
    <servlet-name>paramServlet</servlet-name>
    <servlet-class>com.bjsxt.servlet.ParamServlet</servlet-class>
    <!--初始化参数-->
    <init-param>
        <param-name>abc</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>paramServlet</servlet-name>
    <url-pattern>/ParamServlet</url-pattern>
</servlet-mapping>
    <!--全局参数 可以被多个servlet读取-->
<context-param>
    <param-name>ab</param-name>
    <param-value>utf-8</param-value>
</context-param>
/读取全局参数
       ab = this.getServletContext().getInitParameter("ab");

514 Servlet 中文乱码的处理

1. 请求乱码如何解决?
2. get方式和Post提交方式的区别

[1]get数据的传输是不安全的 ,post数据传递更加安全

[2]get方式数据传递有大小限制 post传输数据没有限制

[3]get传输的数据速度比较快 post比较慢

post提交中文如何解决?

request.setCharacterEncoding(“utf-8”);

public class DoLogin extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //[A]接收Login.jsp传过来的数据
        request.setCharacterEncoding("utf-8");
get提交中文如何解决?方式一:
//解决get方式乱码
//1.获得元素编码的自己数组
byte[] bytes = u.getBytes("ISO-8859-1");
//2.把原始编码的字节数组转成UTF-8编码格式
String str = new String(bytes,"utf-8");

System.out.println("后"+str);

//[B]数据处理--拿着用户和密码去数据库作比较
boolean flag = false;
if("尚学堂".equals(str)&&"123".equals(p)){
    flag =true;
}

方式二:

在server.xml中指定对应的服务器编码

URIEncoding=“utf-8”

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值