Servlet相关概念及其功能使用

本文详细介绍了Servlet的概念、创建及使用,包括Servlet生命周期、HTTP协议解析、Servlet接口与类的使用、请求与响应处理、页面跳转以及解决乱码问题。通过实例展示了Servlet在处理请求、响应和数据传递中的应用,帮助读者深入理解Servlet的工作原理。

一、Servlet概述

1、什么是sevlet

Servlet 是Java Server Applet的简称,称为小服务器程序,用Java编写的服务器端程序,主要功能交互式地浏览和修改数据,生成动态Web内容。

Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

Servlet编程需要使用到javax.servlet 和 javax.servlet.http两个包下面的类和接口,在所有的类和接口中,javax.servlet.Servlet 接口最为重要。所有的servlet程序都必须实现该接口或者继承实现了该接口的类。

javax.servlet.ServletConfig;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
javax.servlet.http.Cookie;

2、servlet入门程序

项目创建:idea选择Java Enterprise>选择javaEE7版本+tomcat+web模块
在这里插入图片描述
1)、在src创建package
2)、选中刚刚创建的包,右键–>New–>Servlet
3)、第一个Servlet代码如下:

@WebServlet(value = "/hello.html")
public class Servletdemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().print("hello servlet");//以流的方式响应到请求页面
        System.out.println("页面请求成功!");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request,response);
    }
}

4)、配置tomcat并启动
5)、浏览器输入网址访问:http://localhost:8080/hello.html
在这里插入图片描述

3、常见错误解决方法

  • (1)HTTP Status 404 资源找不到
    解决方法:查看Tomcat的webapps目录下找到当前项目在WEB-INF下的classes内能否找到刚刚的class文件
    如果有,重新启动Tomcat
    如果没有,在Eclipse中选择Project–>clean让Eclipse清空缓存并重新构建项目,再次运行
    idea中,把out目录的内容删除,然后重新运行。
  • (2)serlvet地址配置重复
  • (3)serlvet地址配置错误,比如没有写/ Invalid <url-pattern>

4、HTTP协议

1)、什么是HTTP协议

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议,是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式。

HTTP协议的主要特点如下:
1.支持客户端/服务器模式。
2.简单快速: 客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活: HTTP允许传输任意类型的数据对象。传输的类型由Content-Type加以标记。
4.无连接: 无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态: HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

2、Http协议的通信

HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
1)、 建立TCP连接
在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能进行更高层协议的连接。因此,首先要建立TCP连接,一般TCP连接的端口号是80

2)、 浏览器向Web服务器发送请求命令
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令
例如:GET /sample/hello.html HTTP/1.1

3、 浏览器发送请求头信息
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。

4)、 Web服务器应答
客户机向服务器发出请求后,服务器会客户机回送应答,
HTTP/1.1 200 OK
应答的第一部分是协议的版本号和应答状态码

5)、 Web服务器发送应答头信息
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。

6)、 Web服务器向浏览器发送数据
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据

7)、 Web服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码

Connection:keep-alive

TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽

3)、请求和响应数据格式

HTTP请求报文

当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息(请求报文),HTTP请求信息由4部分组成:
1 请求行 请求方法/地址 URI协议/版本
2 请求头(Request Header)
3 空行
4 请求正文

HTTP请求的例子:

POST /hello HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Language:zh-CN,zh;q=0.8,en-GB;q=0.6,en;q=0.4
Connection:Keep-Alive
Host:localhost:8080
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Accept-Encoding:gzip, deflate, br

username=zhangsan&age=20&add=beijing
HTTP响应报文

HTTP应答与HTTP请求相似,HTTP响应也由4个部分构成,分别是:

1、状态行
2、响应头(Response Header)
3、空行
4、响应正文

HTTP/1.1 200 OK   //状态行
Server: nginx
Date: Tue, 31 May 2016 02:09:24 GMT
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With,access_token,access-token,content-type,multipart/form-data,application/x-www-form-urlencoded
Access-Control-Allow-Methods: GET,POST,OPTIONS
Content-Length: 49

<!DOCTYPE html>   //正文
<html>  
	<head>
		<title>网页标题</title>
		<meta charset="utf-8">
	</head>
	<body>
		网页内容
	</body>
</html>

二、Servlet使用

1、Servlet核心接口和类

Servlet接口

在ServletAPI中最重要的是Servlet接口,所有Servlet都会直接或间接的与该接口发生联系,或是直接实现该接口,或间接继承自实现了该接口的类。

该接口包括以下五个方法:

//初始化servlet方法
init(ServletConfig config)
//获取Servlet配置
ServletConfig getServletConfig()
//服务方法:执行处理浏览器请求的方法
service(ServletRequest req,ServletResponse res)
//获取servlet信息:作者版权
String getServletInfo()
//销毁方法
destroy( )

处理方式:
(1)第一次访问Servlet时,服务器会创建Servlet对象,并调用init方法,再调用service方法
(2)第二次再访问时,Servlet对象已经存在,不再创建,执行service方法
(3)当服务器停止,会释放Servlet,调用destroy方法。

GenericServlet抽象类

GenericServlet 使编写 servlet 变得更容易。它提供生命周期方法 init 和 destroy 的简单实现,要编写一般的 servlet,只需重写抽象 service方法即可。

HttpServlet类

是继承GenericServlet的基础上进一步的扩展。
提供将要被子类化以创建适用于 Web 站点的 HTTP servlet 的抽象类。HttpServlet 的子类至少必须重写一个方法,该方法通常是以下这些方法之一:
doGet,如果 servlet 支持 HTTP GET 请求
doPost,用于 HTTP POST 请求
doPut,用于 HTTP PUT 请求
doDelete,用于 HTTP DELETE 请求
initdestroy,用于管理 servlet 的生命周期内保存的资源
getServletInfoservlet 使用它提供有关其自身的信息

2、Servlet的两种创建方式

Servlet的第一种创建方式:继承HttpServlet(常用)
Servlet创建的第二种方式:实现接口Servlet(需要全部实现接口方法)

3、Servlet的两种配置方式

1)、第一种注解式配置 Servlet3.0及以后 :

@WebServlet("/hello.html")
public class HelloServlet extends HttpServlet {

使用注解方式:

注解类 WebServlet
name:serlvet名字 (可选)
value: 配置url路径
urlPatterns:配置url路径 ,和value作用一样,不能同时使用
loadOnStartup:配置Servlet的创建的时机, 如果是0或者正数 启动程序时创建,如果是负数,则访问时创建。数字越小优先级越高。
initParams:配置Servlet的初始化参数

2)、第二种web.xml配置 Servlet所有版本都支持:
以下xml配置相当于

@WebServlet(value="/hello.html",name="Servletdemo1")
<?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_3_1.xsd"
         version="3.1">
    <display-name>Servletdemo1</display-name>
    <!--Servlet配置  -->
    <servlet>
        <!--名称  -->
        <servlet-name>Servletdemo1</servlet-name>
        <!--Servlet的全称类名  -->
        <servlet-class>com.booy.servletdemo1.Servletdemo1</servlet-class>
        <!--启动的优先级,数字越小越先起作用  -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--映射配置  -->
    <servlet-mapping>
        <!--名称  -->
        <servlet-name>Servletdemo1</servlet-name>
        <!--资源的匹配规则:精确匹配  -->
        <url-pattern>/hello.html</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>hello.html</welcome-file>
    </welcome-file-list>
</web-app>

容器在进行url-pattern配置的时候是遵循一定的匹配原则的
url-pattern定义匹配规则,取值说明:

  • 精确匹配 /具体的名称:只有url路径是具体的名称的时候才会触发Servlet
  • 后缀匹配 .xxx:只要是以xxx结尾的就匹配触发Servlet
  • 通配符匹配 / :匹配所有请求,包含服务器的所有资源
  • 通配符匹配 / :匹配所有请求,包含服务器的所有资源,不包括.jsp
load-on-startup
  • 1元素标记容器是否应该在web应用程序启动的时候就加载这个servlet。
  • 2它的值必须是一个整数,表示servlet被加载的先后顺序。
  • 3如果该元素的值为负数或者没有设置,则容器会当Servlet被请求时再加载。
  • 4如果值为正整数或者0时,表示容器在应用启动时就实例化并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载。值相同时,容器就会自己选择顺序来加载。
<init-param>
      <param-name>name</param-name>
      <param-value>张三</param-value>
</init-param>
  • 1 init-param元素用来定义Servlet启动的参数,可以定义多个
  • 2 param-name表示参数名称
  • 3 param-value表示参数值

4、Servlet生命周期

阶段一、实例化(调用构造方法)
实例化阶段是Servlet生命周期中的第一步,由Servlet容器调用Servlet的构造器创建一个具体的Servlet对象的过程。而这个创建的时机可以是在容器收到针对这个组件的请求之后,即用了才创建;也可以在容器启动之后立刻创建实例,而不管此时Servlet是否使用的上。使用如下代码可以设置Servlet是否在服务器启动时就执行创建

<load-on-startup>1</load-on-startup>

阶段二、初始化(init方法)
Servlet在被加载实例化之后,必须要初始化它。在初始化阶段,init()方法会被调用。这个方法在javax.servlet.Servlet接口中定义。其中,方法以一个ServletConfig类型的对象作为参数。ServletConfig对象由Servlet引擎负责创建,从中可以读取到事先在web.xml文件中通过<init-param>节点配置的多个name-value名值对。ServletConfig对象还可以让Servlet接受一个ServletContext对象。

一般情况下,init方法不需要编写,因GenericServlet已经提供了init方法的实现,并且提供了getServletConfig方法来获得ServletConfig对象。
注:init方法只被执行一次

阶段三、就绪/服务
Servlet被初始化以后就处于能够响应请求的就绪状态。每个对Servlet的请求由一个ServletRequest对象代表,Servlet给客户端的响应由一个ServletResponse对象代表。当客户端有一个请求时,容器就会将请求与响应对象转给Servlet,以参数的形式传给service方法。service方法由javax.servlet.Servlet定义,由具体的Servlet实现
HttpServlet将service方法拆分了。doGet和doPost

阶段四、销毁
Servlet容器在销毁Servlet对象时会调用destroy方法来释放资源。通常情况下Servlet容器停止或者重新启动都会引起销毁Servlet对象的动作,但除此之外,Servlet容器也有自身管理Servlet对象的准则,整个生命周期并不需要人为进行干预
代码:

@WebServlet(name = "ServletInit",value = "/helloservlet.html",loadOnStartup = -1,initParams = @WebInitParam(name = "paramname",value = "张三"))
public class ServletInit extends HttpServlet {
    public ServletInit() {
        System.out.println("1、servlet实例化了");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("2、servlet初始化了,paramname="+getInitParameter("paramname"));
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("3、执行了服务");
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().print("hello,servlet!!!");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request,response);
    }
    @Override
    public void destroy() {
        System.out.println("4、servlet销毁了");
    }
}

运行结果:
在这里插入图片描述

5、获取请求参数

html页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>欢迎页面</title>
</head>
<body>
<h1>欢迎你</h1>
<div>
    <form action="success.html" method="post">
        <label>姓名:</label><input name="name"><br/>
        <label>年龄:</label><input  name="age"><br/>
        <input type="submit" value="提交">
    </form>
</div>
</body>
</html>

seevlet:

@WebServlet("/success.html")
public class Servletdemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取表单提交的姓名
        String name=request.getParameter("name");
        //获取年龄
        String age=request.getParameter("age");
        //服务端输出打印
        System.out.println(request.getRemoteAddr()+"发来信息:姓名:"+name+"---->年龄:"+age);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

6、请求方式

浏览器默认get请求

GET请求

GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连
GET提交的数据大小有限制(因为浏览器对URL的长度有限制)
GET方式提交数据,会带来安全问题
效率高

对应的Servlet的方法是doGet

POST请求

POST方法是把提交的数据放在HTTP包的Body中
POST方法提交的数据没有限制
POST提交的数据相对安全
效率相对没有GET高

对应的Servlet的方法是doPost

表单数据请求响应示例:

package com.tomcat;

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("/ServletDemo")
public class ServletDemo extends HttpServlet {
    //request请求,response响应
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置接收到的请求体信息为utf-8编码
        request.setCharacterEncoding("utf-8");
        //没有在响应头声明编码,使用时还需要在输出时输出整个html声明
        //response.setCharacterEncoding("utf-8");
        //设置响应体文本格式和编码
        response.setContentType("text/html;charset=utf-8");
        //获取请求体的内容
        String username = request.getParameter("username");
        String phone = request.getParameter("phone");
        System.out.println(username+"->"+phone);
        //给请求体响应
        PrintWriter writer = response.getWriter();
        writer.print("<h2>提交成功!!!</h2>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
<meta charset="UTF-8">
<form action="ServletDemo" method="post">
    用户名:<input type="text" name="username">
    <br />
    联系方式:<input type="text" name="phone">
    <br />
    <input type="submit" value="提交">
</form>

7、中文乱码处理

产生乱码,就是因为服务器和客户端沟通的编码不一致造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接收

GET中文乱码
在Tomcat7及以下
客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1这个字符编码来接收数据,服务器和客户端沟通的编码不一致因此才会产生中文乱码的。解决办法:在接收到数据后,先获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题。

Tomcat8的版本中GET基本就不会乱码了,因为服务器对url的编码格式可以进行自动转换
编码转换:

String name=request.getParameter("name");
name=new String(name.getBytes("ISO8859-1"),"UTF-8");

POST乱码
由于客户端是以UTF-8字符编码将表单数据传输到服务器端的,因此服务器也需要设置以UTF-8字符编码进行接收,要想完成此操作,服务器可以直接使用从ServletRequest接口继承而来的"setCharacterEncoding(charset)"方法进行统一的编码设置。

Servlet输出中文内容
浏览器识别不到返回的中文是什么编码格式,就会默认使用GB2312,如果返回的是UTF-8格式的那么在浏览器上就会显示乱码的问题

解决内容中的乱码

response.setContentType("text/html;charset=UTF-8");//方式一
response.setCharacterEncoding("UTF-8");//方式二:输出一个完整的网页

8、访问WEB-INF下的资源

web目录下非WEB-INF下的资源,可以直接输入文件名就能直接访问,这样很不安全。
而WEB-INF下的资源,应用服务器把它指为禁访目录,即直接在浏览器里是不能访问到的,需要通过servlet才能访问
访问WEB-INF下文件代码如下:

@WebServlet("/index.html")
public class Servletdemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //servlet配置WEB-INF下的文件通过servlet能够访问
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/index.html");
        requestDispatcher.forward(request,response);
        System.out.println("访问成功");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request,response);
    }
}

9、Servlet线程安全问题

1)、线程安全问题

因为每次请求都会创建一个线程,如果多人同时请求,那么就会存在多个线程操作同一个Servlet对象,那么如果在对应的方法中操作了成员变量,就有可能产生线程安全的问题。

2)、如何保证线程安全

1、synchronized
将存在线程安全问题的代码放到同步代码块中

2、实现SingleThreadModel接口
servlet实现SingleThreadModel接口后,每个线程都会创建servlet实例,这样每个客户端请求就不存在共享资源的问题,但是servlet响应客户端请求的效率太低,所以已经淘汰。

3、尽可能只使用局部变量

三、页面跳转

Java Web服务端控制页面跳转主要有两种:重定向和转发

1、重定向

重定向就是通过各种方法将网络请求重新定个方向转到其它位置。
常用的重定向有301和302
301:永久重定向
302:临时重定向
虽然都能实现重定向,在实际开发中,如果网站系统不针对c端用户,即seo优化处理,为了方便可以直接采用302的方式,否则一般应该遵循重定向的语义采用301。如在http跳转到https这样的应该是永久重定向。

实现原理:
如302重定向,客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器–》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址----》服务器根据此请求寻找资源并发送给客户。

特点:
1、重定向是客户端行为。
2、重定向是浏览器做了至少两次的访问请求。
3、重定向浏览器地址改变。
4、重定向两次跳转之间传输的信息会丢失(request范围)。
5、重定向可以指向任何的资源,包括当前应用程序中的其他资源,同一个站点上的其他应用程序中的资源,其他站点的资源。注意:传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录
示例:
301跳转:

@WebServlet("/ServletDemo4")
public class ServletDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	//设置响应状态码
        response.setStatus(301);
        //设置响应头信息设置响应信息头
        response.setHeader("Location","ServletDemo");
        System.out.println("不想处理");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

302跳转:

@WebServlet("/ServletDemo")
public class ServletDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendRedirect("http://www.baidu.com");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

2、请求转发

原理:
客户浏览器发送http请求----》web服务器接受此请求–》调用内部的一个方法在容器内部完成请求处理和转发动作----》将目标资源发送给客户。在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。

request.getRequestDispacther("/index.html").forword(request,response); 

特点:
1,转发是服务器行为
2,转发是浏览器只做了一次访问请求
3,转发浏览器地址不变
4,转发两次跳转之间传输的信息不会丢失,所以可以通过request进行数据的传递
5,转发只能将请求转发给同一个WEB应用中的组件
注意:如果创建RequestDispatcher 对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。

3、网络路径

绝对路径: 用在不同网站之间的跳转,比如:http://www.baidu.com/aaa/1.jpg

相对路径: 用在同一个网站中, aaa/1.jpg,仅限静态资源,如果页面比较多,并且使用框架,会出现混乱。

根路径:根指定就是主机名(服务器) /index/loginservlet (/ 表示 http://localhost:8080/)

/index/loginservlet 如果在浏览器中使用 / 表示 http://localhost:8080/

/loginservlet 如果是在服务器中使用 / 表示 /index

四、response对象

在Servlet中可以使用的内置对象主要有:request、response、application、session、out(PrintWriter)。

1、ServletResponse简介

​ 定义辅助 servlet 将响应发送到客户端的对象。servlet 容器创建 ServletResponse 对象,并将它作为参数传递给 servlet 的 service 方法。 要发送 MIME 正文响应中的二进制数据,请使用 getOutputStream 返回的 ServletOutputStream。要发送字符数据,请使用 getWriter 返回的 PrintWriter 对象。

2、HttpServletResponse介绍

扩展 ServletResponse 接口以提供特定于 HTTP 的发送响应功能。例如,该接口拥有访问 HTTP 头和 cookie 的方法。 客户端向服务器发起的都是HTTP协议操作,所以我们大部分使用HttpServletResponse对象作为直接操作对象!

3、HttpServletResponse 常用API介绍

方法名称作用
setStatus(int code)设置响应状态码:200 成功 302 临时重定向 304 处理缓存 404 Not Found没有找到资源,500 服务器错误
setHeader(name,value)设置响应信息头
setCharacterEncoding(String);设置编码格式
setContentType(String)设置返回数据mimetype
getWriter()获取字符输出流
getOutputStream()获取字节输出流

4、设置返回字符编码格式

方法一:
可以解决返回字符串乱码问题,但是需要将返回的字符串封装到html代码中.操作繁琐!

response.setCharacterEncoding("utf-8");

方法二
方案按相对简单,通过设置响应头告知浏览器解析字符串的编码格式!

 response.setHeader("Content-type","text/html;charset=UTF-8")

方法三(推荐)
利用setContentType这种综合性的写法解决问题!此方法也是开发中常用的方法!方便!

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

五、request对象

1、ServletRequest介绍

定义将客户端请求信息提供给某个 servlet 的对象。servlet 容器创建ServletRequest 对象,并将该对象作为参数传递给该 servlet 的service方法。

2、HttpServletRequest介绍

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

小结:同响应相同,客户端请求协议都是基于HTTP所以我们选用HttpServletRequest来操作用户发送过来的请求的数据!

3、HttpServletRequest常用API

URL:Uniform Resource Location (统一资源定位符) 网址
URI :Uniform Resource Identifier (统一资源标识符) URI包含URL

1)、获取请求路径相关参数

  • getRequestURL方法:返回客户端发出请求时的完整URL。
  • getRequestURI方法:返回请求行中的资源名部分。
  • getQueryString 方法:返回请求行中的参数部分。
  • getRemoteAddr方法:返回发出请求的客户机的IP地址
  • getRemoteHost方法:返回发出请求的客户机的完整主机名
  • getRemotePort方法:返回客户机所使用的网络端口号
  • getLocalAddr方法:返回WEB服务器的IP地址。
  • getLocalName方法:返回WEB服务器的主机名
  • getMethod得到客户机请求方式

2)、获取请求头信息

  • getHead(name)方法
  • getHeaders(String name)方法
  • getHeaderNames方法

3)、获取请求正文参数

  • getParameter(name)方法
  • getParameterValues(String name)方法
  • getParameterNames方法
  • getParameterMap方法 //做框架用,非常实用
  • getInputStream方法 获取输入流

4、封装请求参数

将数据封装到实体类上

创建一个对应的实体类!

实体类要变量命名和变量类型都有相应的要求,要求变量名跟提交参数的key相同,变量跟参数类型相同!

public class User {
 
	private String username;
	private String password;
	private String sex;
	private String[] hobby;
 	//getter/setter 
} 

第一种方式:使用getParameter获取

String username = req.getParameter("username");
String password=req.getParameter("password");
String gender=req.getParameter("sex");
String[] hobby = req.getParameterValues("hobby");

User user=new User(username,password,sex,hobby);
System.out.println(user.toString());

第二种方式:使用反射进行解析

            //表单的name值和value值
		   //key  name值  value  values值
		   Map<String, String[]> parameterMap = request.getParameterMap();
		  
		   User bean = new User();
		   
		   Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
		   
		   for (Entry<String, String[]> entry : entrySet) {
			//entry map中的一条
			   //username password sex
			   String key = entry.getKey();
			   String[] value = entry.getValue();
			   
			   try {
				PropertyDescriptor descriptor = 
						   new PropertyDescriptor(key, User.class);
				
				Method set = descriptor.getWriteMethod();
				
				/**
				 * 参数:哪个对象的set方法
				 * password username sex
				 */
				if (value.length == 1) {
					set.invoke(bean, value[0]);
				}else{
					set.invoke(bean, (Object)value);
				}		
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
   
		  }

第三种方式:使用Apache BeanUtils进行快速映射

1.导入beanutils对应jar包、logging日志、commons-collections-3.2.1.jar
2.映射

BeanUtils.populate(bean2, request.getParameterMap());	
System.out.println(bean2);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值