JavaWEB-(十七)Servlet的应用

本文最后更新于:December 3, 2021 pm

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

目录

1.request对象

request用来请求数据。
在Servlet中用来处理客户端请求需要用 doGet()或者 doPost() 方法的request对象。

1.1 Get和Post的区别

  1. Get请求
  • get提交的数据会放在URL之后,以问号(?)分割URL和传输数据,参数之间以 & 相连。
  • get方式为明文传递,数据量小,不安全。但效率高,浏览器默认请求方式为 Get 请求。
  • 对应的Servlet中的方法为 doGet() 。
  1. Post 请求
  • post 方法是把提交的数据放在HTTP包的Body中。
  • 密文传递数据,数据量大,安全。但效率相对没有Get高。
  • 对应的Servlet中的方法为 doPost() 。

1.2 request主要方法

方法名 说明
String getParameter(String name) 根据表单组件名称获取提交数据
void setCharacterEncoding(String charset) 指定每个请求的编码方式

1.3 实例

1.3.1 Get使用

HelloServlet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.tothefor.requesttest;

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

@WebServlet(name = "helloServlet", value = "/hs")
public class HelloServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("用户:" + username + " " + password);
}

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

register.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<!--action中项目名称和实现servlet的类的url-pattern-->
<form action="/requestTest_war_exploded/hs" method="get">
用户名:<input type="text" name="username"> <br>
密 码:<input type="password" name="password"> <br>
<input type="submit" value="注册">
</form>

</body>
</html>

📢注意:表单里面必须是name属性,不能的id属性!!!2021/11/28掉坑了。。。

网页输入测试:

1
2
3
4
5
6
7
# 用户名  密码
in:qe er
out:qe er


in:龙 long
out:龙 long
  1. get请求收参问题
  • 产生乱码是因为服务器和客户端沟通的编码不一样造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接受。
  1. get中文乱码
  • 在Tomcat7及以下版本,客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1字符编码来接收数据,服务器和客户端沟通的编码不一致才会产生中文乱码。

  • 解决办法:在接受到数据后,先获取request对象以ISO8859-1字符编码接受到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题。

  • 需要注意的是:Tomcat8版本中get方式不会出现乱码了,因为服务器对URL的编码格式可以进行自动转换。

如果实在还是有乱码情况,可以参考以下解决代码:

1
2
3
4
5
6
7
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
username = new String(username.getBytes("ISO8859-1"),"UTF-8");
String password = req.getParameter("password");
System.out.println("用户:" + username + " " + password);
}

1.3.2 Post使用

需要注意的是,Post方法并没有解决乱码问题。输入中文会出现乱码。

因为客户端是以UTF-8字符编码将表单数据传输到服务器的,因此服务器也需要配置以UTF-8字符编码进行接收。需要使用从ServletRequest接口继承而来的setCharacterEncoding(charset)方法进行统一的编码设置。

1
2
3
4
5
6
7
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); //对request请求对象设置统一的编码,对Get无效。
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("用户:" + username + " " + password);
}

2.response对象

response用来响应数据。
response对象用于响应客户端请求并向客户端输出信息。

2.1 response主要方法

方法名称 作用
setHeader(name,value) 设置响应信息头
setContentType(String) 设置响应文件类型、响应式的编码格式
setCharacterEncoding(String) 设置服务端响应内容编码格式
getWriter() 获取字符输出流

实例:实现是在request实例的基础上

1
2
3
4
5
6
7
8
9
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("用户:" + username + " " + password);
PrintWriter cout = resp.getWriter();
cout.println("注册成功");
}

当访问网页时,发现出现了中文乱码。这个问题和request出现乱码的原因一样。因为服务器默认采用ISO8859-1编码响应内容。

2.2 解决输出中文乱码

    1. 设置服务器端响应的编码格式。
    1. 设置客户端响应内容的头内容的文件类型及编码格式。

解决办法一(不推荐)

1
2
resp.setCharacterEncoding("UTF-8"); //设置响应编码格式为UTF-8
resp.setHeader("Content-type","text/html;charset=UTF-8");

但自己在实际测试中,发现只要第一句代码也可以解决乱码问题。不同的是,输出在网页上的字体不同,大小也不同。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");//解决控制台的乱码问题

//解决输出到网页的乱码问题
resp.setCharacterEncoding("UTF-8");
resp.setHeader("Content-type","text/html;charset=UTF-8");

String username = req.getParameter("username");
String password = req.getParameter("password");
//输出在控制台上
System.out.println("用户:" + username + " " + password);
//输出在网页上
PrintWriter cout = resp.getWriter();
cout.println("注册成功");
}

解决办法二(推荐)

同时设置服务端的编码格式和客户端响应的文件类型及响应时的编码格式。

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

实例:

1
2
3
4
5
6
7
8
9
10
11
12
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");//解决控制台的乱码问题

resp.setContentType("text/html;charset=UTF-8");//解决输出到网页的乱码问题

String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("用户:" + username + " " + password);
PrintWriter cout = resp.getWriter();
cout.println("注册成功");
}