Writing Service Methods
Getting Information from Requests
A request contains data passed between a client and the servlet. All requests implement the ServletRequest
interface. This interface defines methods for accessing the following information:
- Parameters, which are typically used to convey information between clients and servlets
- Object-valued attributes, which are typically used to pass information between the web container and a servlet or between collaborating servlets
- Information about the protocol used to communicate the request and about the client and server involved in the request
- Information relevant to localization
You can also retrieve an input stream from the request and manually parse the data. To read character data, use the BufferedReader
object returned by the request’s getReader
method. To read binary data, use the ServletInputStream
returned by getInputStream
.
HTTP servlets are passed an HTTP request object, HttpServletRequest
, which contains the request URL, HTTP headers, query string, and so on. An HTTP request URL contains the following parts:
http://[host]:[port][request-path]?[query-string]
The request path is further composed of the following elements.
- Context path: A concatenation of a forward slash (
/
) with the context root of the servlet’s web application. - Servlet path: The path section that corresponds to the component alias that activated this request. This path starts with a forward slash (
/
). - Path info: The part of the request path that is not part of the context path or the servlet path.
You can use the getContextPath
, getServletPath
, and getPathInfo
methods of the HttpServletRequest
interface to access this information. Except for URL encoding differences between the request URI and the path parts, the request URI is always comprised of the context path plus the servlet path plus the path info.
Query strings are composed of a set of parameters and values. Individual parameters are retrieved from a request by using the getParameter
method. There are two ways to generate query strings.
- A query string can explicitly appear in a web page.
- A query string is appended to a URL when a form with a
GET
HTTP method is submitted.
实践
环境
操作系统:
Windows 10 x64
集成开发环境:
Eclipse IDE for Enterprise Java and Web Developers (includes Incubating components)
Version: 2021-09 (4.21.0)
Build id: 20210910-1417
服务器:
apache-tomcat-9.0.55
新建项目
新建 Dynamic Web Project:
新建一个 HelloServlet
类,继承自 HttpServlet
:
- 使用
@WebServlet
注解,指定urlPatterns
属性 - 重写
doGet
方法,用于处理GET
请求
package com.mk.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = { "/hello", "/hello/*" })
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String requestURL = request.getRequestURL().toString();
String requestURI = request.getRequestURI();
String method = request.getMethod();
String protocol = request.getProtocol();
System.out.println("Request URL: " + requestURL);
System.out.println("Request URI: " + requestURI);
System.out.println("Request Method: " + method);
System.out.println("Protocol: " + protocol);
String scheme = request.getScheme();
String serverName = request.getServerName();
int serverPort = request.getServerPort();
String contextPath = request.getContextPath();
String servletPath = request.getServletPath();
String pathInfo = request.getPathInfo();
String queryString = request.getQueryString();
System.out.println("Scheme: " + scheme);
System.out.println("Server Name: " + serverName);
System.out.println("Server Port: " + serverPort);
System.out.println("Context Path: " + contextPath);
System.out.println("Servlet Path: " + servletPath);
System.out.println("Path Info: " + pathInfo);
System.out.println("Query String: " + queryString);
String localAddr = request.getLocalAddr();
String localName = request.getLocalName();
int localPort = request.getLocalPort();
System.out.println("Local Address: " + localAddr);
System.out.println("Local Name: " + localName);
System.out.println("Local Port: " + localPort);
String remoteAddr = request.getRemoteAddr();
String remoteHost = request.getRemoteHost();
int remotePort = request.getRemotePort();
System.out.println("Remote Address: " + remoteAddr);
System.out.println("Remote Host: " + remoteHost);
System.out.println("Remote Post: " + remotePort);
}
}
测试
启动 Apache Tomcat 服务器,服务器启动成功之后,我们的项目被部署到类似如下的路径中:
访问 http://localhost:8080/hello-servlet/hello,此 URL 映射到 /hello
,控制台输出:
Request URL: http://localhost:8080/hello-servlet/hello
Request URI: /hello-servlet/hello
Request Method: GET
Protocol: HTTP/1.1
Scheme: http
Server Name: localhost
Server Port: 8080
Context Path: /hello-servlet
Servlet Path: /hello
Path Info: null
Query String: null
Local Address: 0:0:0:0:0:0:0:1
Local Name: 0:0:0:0:0:0:0:1
Local Port: 8080
Remote Address: 0:0:0:0:0:0:0:1
Remote Host: 0:0:0:0:0:0:0:1
Remote Post: 55399
访问 http://localhost:8080/hello-servlet/hello/1/2/3/4?username=mk&password=123456,此 URL 映射到 /hello/*
,控制台输出:
注意:Path Info 和 Query String 的值与上一次的区别。
提示:有关 Path Info 和 Query String 的说明,可以参考
getPathInfo
和getQueryString
方法的注释。
Request URL: http://localhost:8080/hello-servlet/hello/1/2/3/4
Request URI: /hello-servlet/hello/1/2/3/4
Request Method: GET
Protocol: HTTP/1.1
Scheme: http
Server Name: localhost
Server Port: 8080
Context Path: /hello-servlet
Servlet Path: /hello
Path Info: /1/2/3/4
Query String: username=mk&password=123456
Local Address: 0:0:0:0:0:0:0:1
Local Name: 0:0:0:0:0:0:0:1
Local Port: 8080
Remote Address: 0:0:0:0:0:0:0:1
Remote Host: 0:0:0:0:0:0:0:1
Remote Post: 55335
在本机(运行服务器的机器)访问:http://192.168.31.135:8080/hello-servlet/hello/1/2/3/4?username=mk&password=123456,控制台输出:
注意:Server Name、Local Address、Local Name、Remote Address 和 Remote Host 的值与上一次的区别。
注意:
192.168.31.135
是我本机的 IP,不是你的,不要完全照搬!
Request URL: http://192.168.31.135:8080/hello-servlet/hello/1/2/3/4
Request URI: /hello-servlet/hello/1/2/3/4
Request Method: GET
Protocol: HTTP/1.1
Scheme: http
Server Name: 192.168.31.135
Server Port: 8080
Context Path: /hello-servlet
Servlet Path: /hello
Path Info: /1/2/3/4
Query String: username=mk&password=123456
Local Address: 192.168.31.135
Local Name: PS2021DBDXHCJX
Local Port: 8080
Remote Address: 192.168.31.135
Remote Host: 192.168.31.135
Remote Post: 55191
使用手机或其他机器(非运行服务器的机器,但与服务器位于同一局域网内)访问 http://192.168.31.135:8080/hello-servlet/hello/1/2/3/4?username=mk&password=123456,控制台输出:
注意:Remote Address 和 Remote Host 的值与上一次的区别。
Request URL: http://192.168.31.135:8080/hello-servlet/hello/1/2/3/4
Request URI: /hello-servlet/hello/1/2/3/4
Request Method: GET
Protocol: HTTP/1.1
Scheme: http
Server Name: 192.168.31.135
Server Port: 8080
Context Path: /hello-servlet
Servlet Path: /hello
Path Info: /1/2/3/4
Query String: username=mk&password=123456
Local Address: 192.168.31.135
Local Name: PS2021DBDXHCJX
Local Port: 8080
Remote Address: 192.168.31.145
Remote Host: 192.168.31.145
Remote Post: 46288
注意:如果在服务器和客户端之间存在代理,那么你无法使用
getRemoteAddr
、getRemoteHost
和getRemotePort
方法获取到关于客户端的地址、主机和端口信息,参考这三个方法的注释。