Servlet技术


Servlet技术

一、Servlet简介

  • Servlet就是sun公司开发动态web的一门技术

  • Sun在这些API中提供了一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:

    • 编写一个类,实现Servlet接口
    • 把开发好的Java类部署到web服务器中
  • 把实现了Servlet接口的Java程序叫做Servlet

  • Servlet接口为HttpServlet的根接口

  • Mavne仓库地址:https://mvnrepository.com/

二、Servlet使用

四大步骤:

  1. 导入Servlet依赖
  2. 继承HttpServlet类 或 实现Servlet接口
  3. 注解配置Servlet访问路径 或 web.xml配置
  4. 浏览器访问 Servlet

1、创建Servlet程序

创建Web项目
在这里插入图片描述
选择Servlet
在这里插入图片描述
在pom.xml中配置 servlet 依赖,也可以通过Tomcat服务器配置

	<dependency>
		     <groupId>javax.servlet</groupId>
		     <artifactId>javax.servlet-api</artifactId>
		     <version>4.0.1</version>
		     <!--在运行时排除该jar包,因为当我们将项目部署到Tomcat时可能出现jar包冲突,Tomcat中默认有该jar包-->
            <scope>provided</scope>
	 </dependency>

编写 index.jsp 文件
在这里插入图片描述

继承HttpServlet类,并重写doGet和doPost方法,Ctrl+O重写方法
在这里插入图片描述
编写 web.xml 配置文件,映射Servlet的URL地址
在这里插入图片描述
使用注解配置Servlet的URL地址
在这里插入图片描述
运行Tomcat服务器
在这里插入图片描述
在这里插入图片描述

2、Servlet的配置

1、web.xml配置Servlet请求路径
  • Servlet3.0之前使用的是web.xml配置
  • 通过web.xml配置Servlet找到对应的页面。
    1、web.xml配置 相当于 Servlet 里的注解 @WebServlet。
    2、@WebServlet注解 和 web.xml 不能同时存在。
    3、servlet 里的 servlet-name 的值自定义。
    4、servlet 里的 servlet-class 需要配置的 Servlet 的位置,包含包名和类名。
    5、servlet-mapping 里的 servlet-name 值,与 servlet 里的 servlet-name 对应必须一样。
    6、servlet-mapping 里的 url-pattern 是映射URL地址必须加上 " / ",与前端的 form 标签中的 action 的值对应,前端中可以不写 " / "
  1. 一个Servlet可以指定一个映射路径

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/sgz</url-pattern>
    </servlet-mapping>
    
  2. 一个Servlet可以指定多个映射路径,需要配置多个 servlet-mapping

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/sgz</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/sgz1</url-pattern>
    </servlet-mapping>  <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/sgz2</url-pattern>
    </servlet-mapping>  <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/sgz3</url-pattern>
    </servlet-mapping>
    
  3. 一个Servlet可以指定通用映射路径

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/sgz/*</url-pattern>
    </servlet-mapping>	
    
  4. 指定一些后缀或者前缀等等
    自定义后缀实现请求映射
    注意:* 前面不能加映射的路径
    只要以 .sgz结尾的都可以:sgz/fsfasfdas.sgz

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.sgz</url-pattern>
    </servlet-mapping>
    
  5. 默认请求路径,直接进入Servlet(不建议配置)

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
2、@WebServlet注解配置Servlet请求路径(常用)
  • Servlet3.0之后使用的是@WebServlet注解配置
  1. 设置一个 urlPatterns 的值
  • name 的值自定义
  • urlPatterns 的值是URL 路径,且必须有 " / ",与前端的 form 标签中的 action 的值对应,前端中可以不写 " / "
@WebServlet(name = "LoginServlet", urlPatterns = "/login")
  1. 设置多个 urlPatterns 的值
  • 使用 {“1”,“2”,“3”,…} 设置多个userPattern的值
@WebServlet(name = "LoginServlet", urlPatterns = {"/login","/submit"})

3、Servlet生命周期

  • Servlet 接口里有三个生命周期方法
    • init:初始化,进去Servlet会执行,只会调用一次
    • service:刷新服务,运行时执行,多次调用
    • destroy:销毁,关闭服务器或退出Web时执行,只会调用一次
/**
 * Servlet 接口里有三个生命周期方法
 * init:初始化
 * service:刷新服务
 * destroy:销毁
 */
@WebServlet(urlPatterns = "/life.do")
public class LifeServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init 初始化被调用");
    }

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service 刷新服务被调用");
    }

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

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

三、ServletConfig接口

  • Servlet运行期间的配置,如编码、Servlet共享等。

1、@WebServlet注解初始化参数initParams

@WebServlet(name = "DemoServlet", urlPatterns = "/ConfigServlet",
        initParams = {@WebInitParam(name = "email", value = "123@qq.com"),
                @WebInitParam(name = "password", value = "123123")})
public class ConfigServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        ServletConfig config = this.getServletConfig();
        String email = config.getInitParameter("email");
        String password = config.getInitParameter("password");
        out.println(email);
        out.println(password);
    }

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

    }
}

四、ServletContext接口

  • web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。

1、web.xml配置初始化参数

getServletContext():获取上下文信息
getInitParameter():获取初始化值,通过 键 获取 值
getInitParameterNames():获取初始化参数名(键)

web.xml配置初始化参数

    <context-param>
        <param-name>姓名</param-name>
        <param-value>沈公子</param-value>
    </context-param>

    <context-param>
        <param-name>age</param-name>
        <param-value>22</param-value>
    </context-param>

方法一

	// 获取上下文信息 getServletContext() ,不然会出现null数据
	ServletContext context = getServletContext();	
	// 获取初始化值 getInitParameter() ,通过 键 获取 值
	String name = context.getInitParameter("姓名");
	String age = context.getInitParameter("age");
	response.getWriter().println(name);
	response.getWriter().println(age);

方法二

	// 获取上下文信息 getServletContext() ,不然会出现null数据
	ServletContext config = getServletContext();	
	// 获取初始化参数名 getInitParameterNames() ,通过 Enumeration 对象进行遍历,获取初始化数据
	Enumeration<String> parameterNames = config.getInitParameterNames();
	// 通过 hasMoreElements() 循环看它是否有元素,有的话就通过 nextElement() 获取参数名称
	while (parameterNames.hasMoreElements()) {
		String name = parameterNames.nextElement();	// 获取键 nextElement()
		String value = config.getInitParameter(name);	// 获取值 getInitParameter()
		response.getWriter().println(name + ":" + value);
	}

2、多个Servlet对象共享数据

getServletContext():获取上下文信息
getAttributeNames():返回Enumeration对象,获取ServletContext中键
setAttribute():设置共享数据
getAttribute():获取共享数据
removeAttribute():删除属性名对应的值

第一个Servlet设置数据,getServletContext() —> setAttribute()

	ServletContext context = getServletContext();	// 获取  getServletContext()
	context.setAttribute("username", "admin");		// 设置共享数据 setAttribute()
	context.setAttribute("password","123123");
	context.setAttribute("age","22");

第二个Servlet获取数据,getServletContext() —> getAttribute()

	ServletContext context = getServletContext();	// 获取  getServletContext()
	String username = (String) context.getAttribute("username");	// 获取共享数据 getAttribute()

获取多个Servlet数据

     ServletContext context = getServletContext();
     // getAttributeNames() 返回Enumeration对象,获取ServletContext中键
        Enumeration<String> enumeration = context.getAttributeNames();
        while (enumeration.hasMoreElements()){
          String name = enumeration.nextElement();
            if (name.equals("username") || name.equals("password") || name.equals("age")){
                Object value = context.getAttribute(name);
                response.getWriter().println(value);
            }
        }

删除ServletContext中的属性

ServletContext context = getServletContext();
        context.setAttribute("username", "root");
        context.setAttribute("password", "123123");
        context.setAttribute("age", "22");
        context.removeAttribute("age"); // removeAttribute():删除键名为age所对应的值

五、HttpServletResponse对象

1、请求重定向

一种资源跳转方式
在这里插入图片描述

  1. 浏览器地址会改变
  2. 可以重定向到任意位置的资源(服务器内部、外部均可)
  3. 两次请求,不能在多个资源使用request共享数据
  4. 需要浏览器的默认路径,所有在编写时加上浏览器默认路径(虚拟目录),需要加 " / "
  5. sendRedirect()
	// 静态获取虚拟路径
   response.sendRedirect("/demo04_war/welcome.html");
   // 动态获取虚拟路径:request.getContextPath()
   response.sendRedirect(request.getContextPath()+"/welcome.html");

2、解决响应中文乱码问题

方法一:(常用)

response.setContentType("text/html;charset=utf-8");

方法二

response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type","text/html;charset=utf-8");

3、状态码相关方法

getStatus():获取响应消息状态码
sendError():一个参数 发送错误状态码,两个参数 发送错误消息提示和状态码

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();    // PrintWriter:字符输出流对象
        // 获取请求参数,通过url地址传参获取 http://localhost:8080/Demo_war_exploded/StatusServlet?param=0
        String str = request.getParameter("param");
        if (str == null) {
            out.println("没有提供请求参数");
        } else if (str.equals("0")) {
            out.println(response.getStatus() + "<br>");	// getStatus():获取响应消息状态码
        } else if (str.equals("1")) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);  //禁止的 403
        } else if (str.equals("2")) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); //没有权限的 401
        } else {
            response.sendError(404, "resource cannot found!");    // 发送错误消息提示和状态码
        //	response.sendError(404);	// 不会在消息中提示,只会显示 404
        }

4、字符方法响应对象

   PrintWriter out = response.getWriter();
   out.println(username);

5、字节方法响应对象

   ServletOutputStream outputStream = response.getOutputStream();
   outputStream.write(username.getBytes());

六、HttpServletRequest对象

可以通过前端的name值获取到前端的数据,HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有消息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获取客户端的所有信息。

1、请求转发

一种在服务器内部的资源跳转方式
在这里插入图片描述

  1. 浏览器地址不会改变
  2. 只能转发到当前服务器的内部资源
  3. 一次请求,可以在转发的资源间使用request共享数据
  4. 指定转发路径时需要加 " / "
  5. getRequestDispatcher().forward()
     	ServletContext context = this.getServletContext();
        context.getRequestDispatcher("/success.jsp").forward(request, response);	  // 合并
        // 请求转发,需要一个请求转发路径,它会走这个转发的路径,请求路径不会改变,必须加 " / "
        // RequestDispatcher request1 = context.getRequestDispatcher("/success.jsp");
        // request1.forward(request,response); // 调用 forward 实现请求转发

2、获取请求数据

  • 请求行

    • String getMethod():获取请求方式:GET
    • String getContextPath():获取虚拟目录:/demo
    • StringBuffer getRequestURL():获取URL:htpp://localhost:8080/demo/a
    • String getRequestURI():获取URI:/demo/a
    • String getQueryString():获取请求参数:username=zhangsan&password=123123
  • 请求头

    • String getHead(String name):根据请求头名称,获取值
  • 请求体

    • ServletInputStream getInputStream():获取字节输入流
    • BufferedReader getReader():获取字符输入流

3、获取请求参数

index.jsp页面

<form action="hello-servlet" method="get">
    用户名:<input type="text" name="username"> <br>
    兴趣:<input type="checkbox" name="happy" value="play"><input type="checkbox" name="happy" value="ect"><input type="checkbox" name="happy" value="he"><input type="checkbox" name="happy" value="pao"><br>
    <input type="submit" value="提交">
</form>

Java代码

  • getParameter():获取单个参数,前端或浏览器地址
  • getParameterValues():获取多个参数(数组),前端或浏览器地址
  • getParameterMap():获取所有参数Map集合
@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        
        // 单个参数
        String username = request.getParameter("username");
        System.out.println(username);
        // 多个参数
        String[] happies = request.getParameterValues("happy");
        for (int i = 0; i < happies.length; i++) {
            System.out.println(happies[i] + " ");
        }
        // 获取所有参数的Map集合
        Map<String, String[]> map = request.getParameterMap();   
        for (String key : map.keySet()) {      // 快捷键:iter
            System.out.print(key+":");         // username:zhangsan lisi
            String[] values = map.get(key);   // 获取值
            for (String value : values) {   // 遍历输出获取的值
                System.out.print(value+" ");
            }
            System.out.println();
        }
        getServletContext().getRequestDispatcher("/success.jsp").forward(request, response);
    }

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

4、Request共享数据

  • 一次请求中才可以在转发资源间使用request共享数据

当前为 Servlet1

	request.setAttribute("username","沈公子");
	request.getRequestDispatcher("/Servlet2").forward(request,response);	// 只有在同一个request才可以共享数据

当前为 Servlet2

	Object username = request.getAttribute("username");
	System.out.println(username);

5、解决请求中文乱码问题

 request.setCharacterEncoding("utf-8");

七、重定向和转发的区别

  • 相同点:
    • 页面都会实现跳转
  • 不同点:
    • 请求转发的时候,url不会产生变化,307,getRequestDispatcher().forward(),不需要tomcat地址,一次请求,可以使用request共享数据,只能访问内部服务器资源,不需要虚拟目录
    • 重定向的时候,url地址栏会发生变化,302,sendRedirect(),需要tomcat地址,两次请求,不可以使用request共享数据,可以访问内部与外部服务器资源,需要虚拟目录

八、IDEA模板创建Servlet

在这里插入图片描述

九、Servlet总结

  • Servlet创建
  • Servlet请求路径配置,两种方式
    • web.xml(四种格式)
    • @WebServlet注解(四种格式)(常用)
  • Servlet生命周期
  • Servlet初始化参数
  • Servlet共享数据
  • 重定向
  • 请求转发
  • 设置状态码
  • 解决乱码问题
  • 获取请求数据
  • 获取请求参数
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值