Java-Servlet
Java Servlet 笔记
Servlet
什么是Servlet?
宏观上说
Servlet 是一个 Java 基于Web技术的组件,通过容器来管理,用于产生动态内容。该容器,有时也称为 Servlet 引擎。它与Web客户端通过一个由容器实现的 请求/响应 范例来进行交互。
代码层面上
Servlet 是 Java EE 中的一个接口:javax.servlet.Servlet
, 位于package javax.servlet
中,其中定义了5个方法。
那servlet是干嘛的?
很简单,接口的作用是什么?规范呗!
servlet接口定义的是一套处理网络请求的规范,所有实现servlet的类,都需要实现它那五个方法,其中最主要的是两个生命周期方法 init()
和 destroy()
,还有一个处理请求的service()
,也就是说,所有实现servlet接口的类,或者说,所有想要处理网络请求的类,都需要回答这三个问题:
- 你初始化时要做什么
- 你接受到请求时要做什么
- 你销毁时要做什么
servlet的本质是什么,它是如何工作的? - Javdroider Hong的回答 - 知乎
https://www.zhihu.com/question/21416727/answer/339012081
Servlet接口源码
Servlet接口的完整源码:
package javax.servlet;
import java.io.IOException;
public interface Servlet {
//初始化
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
//处理http请求
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
public String getServletInfo();
//销毁
public void destroy();
}
HttpServlet 抽象类源码
package javax.servlet.http;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.DispatcherType;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public abstract class HttpServlet extends GenericServlet {
private static final long serialVersionUID = 1L;
private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE";
private static final String HEADER_IFMODSINCE = "If-Modified-Since";
private static final String HEADER_LASTMOD = "Last-Modified";
private static final String LSTRING_FILE =
"javax.servlet.http.LocalStrings";
private static final ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE);
/**
* Does nothing, because this is an abstract class.
*/
public HttpServlet() {
// NOOP
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
protected long getLastModified(HttpServletRequest req) {
return -1;
}
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (DispatcherType.INCLUDE.equals(req.getDispatcherType())) {
doGet(req, resp);
} else {
NoBodyResponse response = new NoBodyResponse(resp);
doGet(req, response);
response.setContentLength();
}
}
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(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_put_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
protected void doDelete(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_delete_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
private static Method[] getAllDeclaredMethods(Class<?> c) {
if (c.equals(javax.servlet.http.HttpServlet.class)) {
return null;
}
Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());
Method[] thisMethods = c.getDeclaredMethods();
if ((parentMethods != null) && (parentMethods.length > 0)) {
Method[] allMethods =
new Method[parentMethods.length + thisMethods.length];
System.arraycopy(parentMethods, 0, allMethods, 0,
parentMethods.length);
System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
thisMethods.length);
thisMethods = allMethods;
}
return thisMethods;
}
protected void doOptions(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
Method[] methods = getAllDeclaredMethods(this.getClass());
boolean ALLOW_GET = false;
boolean ALLOW_HEAD = false;
boolean ALLOW_POST = false;
boolean ALLOW_PUT = false;
boolean ALLOW_DELETE = false;
boolean ALLOW_TRACE = true;
boolean ALLOW_OPTIONS = true;
// Tomcat specific hack to see if TRACE is allowed
Class<?> clazz = null;
try {
clazz = Class.forName("org.apache.catalina.connector.RequestFacade");
Method getAllowTrace = clazz.getMethod("getAllowTrace", (Class<?>[]) null);
ALLOW_TRACE = ((Boolean) getAllowTrace.invoke(req, (Object[]) null)).booleanValue();
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException |
IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// Ignore. Not running on Tomcat. TRACE is always allowed.
}
// End of Tomcat specific hack
for (int i=0; i<methods.length; i++) {
Method m = methods[i];
if (m.getName().equals("doGet")) {
ALLOW_GET = true;
ALLOW_HEAD = true;
}
if (m.getName().equals("doPost"))
ALLOW_POST = true;
if (m.getName().equals("doPut"))
ALLOW_PUT = true;
if (m.getName().equals("doDelete"))
ALLOW_DELETE = true;
}
String allow = null;
if (ALLOW_GET)
allow=METHOD_GET;
if (ALLOW_HEAD)
if (allow==null) allow=METHOD_HEAD;
else allow += ", " + METHOD_HEAD;
if (ALLOW_POST)
if (allow==null) allow=METHOD_POST;
else allow += ", " + METHOD_POST;
if (ALLOW_PUT)
if (allow==null) allow=METHOD_PUT;
else allow += ", " + METHOD_PUT;
if (ALLOW_DELETE)
if (allow==null) allow=METHOD_DELETE;
else allow += ", " + METHOD_DELETE;
if (ALLOW_TRACE)
if (allow==null) allow=METHOD_TRACE;
else allow += ", " + METHOD_TRACE;
if (ALLOW_OPTIONS)
if (allow==null) allow=METHOD_OPTIONS;
else allow += ", " + METHOD_OPTIONS;
resp.setHeader("Allow", allow);
}
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
int responseLength;
String CRLF = "\r\n";
StringBuilder buffer = new StringBuilder("TRACE ").append(req.getRequestURI())
.append(" ").append(req.getProtocol());
Enumeration<String> reqHeaderEnum = req.getHeaderNames();
while( reqHeaderEnum.hasMoreElements() ) {
String headerName = reqHeaderEnum.nextElement();
buffer.append(CRLF).append(headerName).append(": ")
.append(req.getHeader(headerName));
}
buffer.append(CRLF);
responseLength = buffer.length();
resp.setContentType("message/http");
resp.setContentLength(responseLength);
ServletOutputStream out = resp.getOutputStream();
out.print(buffer.toString());
out.close();
}
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
private void maybeSetLastModified(HttpServletResponse resp,
long lastModified) {
if (resp.containsHeader(HEADER_LASTMOD))
return;
if (lastModified >= 0)
resp.setDateHeader(HEADER_LASTMOD, lastModified);
}
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException(lStrings.getString("http.non_http"));
}
service(request, response);
}
}
class NoBodyResponse extends HttpServletResponseWrapper {
private final NoBodyOutputStream noBody;
private PrintWriter writer;
private boolean didSetContentLength;
// file private
NoBodyResponse(HttpServletResponse r) {
super(r);
noBody = new NoBodyOutputStream(this);
}
// file private
void setContentLength() {
if (!didSetContentLength) {
if (writer != null) {
writer.flush();
}
super.setContentLength(noBody.getContentLength());
}
}
// SERVLET RESPONSE interface methods
@Override
public void setContentLength(int len) {
super.setContentLength(len);
didSetContentLength = true;
}
@Override
public void setContentLengthLong(long len) {
super.setContentLengthLong(len);
didSetContentLength = true;
}
@Override
public void setHeader(String name, String value) {
super.setHeader(name, value);
checkHeader(name);
}
@Override
public void addHeader(String name, String value) {
super.addHeader(name, value);
checkHeader(name);
}
@Override
public void setIntHeader(String name, int value) {
super.setIntHeader(name, value);
checkHeader(name);
}
@Override
public void addIntHeader(String name, int value) {
super.addIntHeader(name, value);
checkHeader(name);
}
private void checkHeader(String name) {
if ("content-length".equalsIgnoreCase(name)) {
didSetContentLength = true;
}
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return noBody;
}
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException {
if (writer == null) {
OutputStreamWriter w;
w = new OutputStreamWriter(noBody, getCharacterEncoding());
writer = new PrintWriter(w);
}
return writer;
}
}
class NoBodyOutputStream extends ServletOutputStream {
private static final String LSTRING_FILE =
"javax.servlet.http.LocalStrings";
private static final ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE);
private final HttpServletResponse response;
private boolean flushed = false;
private int contentLength = 0;
// file private
NoBodyOutputStream(HttpServletResponse response) {
this.response = response;
}
// file private
int getContentLength() {
return contentLength;
}
@Override
public void write(int b) throws IOException {
contentLength++;
checkCommit();
}
@Override
public void write(byte buf[], int offset, int len) throws IOException {
if (buf == null) {
throw new NullPointerException(
lStrings.getString("err.io.nullArray"));
}
if (offset < 0 || len < 0 || offset+len > buf.length) {
String msg = lStrings.getString("err.io.indexOutOfBounds");
Object[] msgArgs = new Object[3];
msgArgs[0] = Integer.valueOf(offset);
msgArgs[1] = Integer.valueOf(len);
msgArgs[2] = Integer.valueOf(buf.length);
msg = MessageFormat.format(msg, msgArgs);
throw new IndexOutOfBoundsException(msg);
}
contentLength += len;
checkCommit();
}
@Override
public boolean isReady() {
// TODO SERVLET 3.1
return false;
}
@Override
public void setWriteListener(javax.servlet.WriteListener listener) {
// TODO SERVLET 3.1
}
private void checkCommit() throws IOException {
if (!flushed && contentLength > response.getBufferSize()) {
response.flushBuffer();
flushed = true;
}
}
}
Servlet需要搭配容器使用
仅仅有一个实现了Servlet接口的Servlet实现类是无法处理http请求的,因为servlet中并没有监听8080端口的代码,所以servlet不会直接和客户端打交道。
那请求怎么来到servlet呢?
答案是servlet容器,比如我们最常用的tomcat,同样,你可以随便谷歌一个servlet的hello world教程,里面肯定会让你把servlet部署到一个容器中,不然你的servlet压根不会起作用。
tomcat才是与客户端直接打交道的家伙,他监听了端口,请求过来后,根据url等信息,确定要将请求交给哪个servlet去处理,然后调用那个servlet的service方法,service方法返回一个response对象,tomcat再把这个response返回给客户端。
socket 是具体负责发送请求的。servlet 不管收发,只管处理请求生成响应,比 socket 的层次高。servlet 不能脱离 tomcat 等容器存在,他只是流水线上的一个部件。
servlet的本质是什么,它是如何工作的? - Javdroider Hong的回答 - 知乎
https://www.zhihu.com/question/21416727/answer/339012081
servlet与filter
Filter对用户请求进行预处理,接着将请求HttpServletRequest交给Servlet进行处理并生成响应,最后Filter再对服务器响应HttpServletResponse进行后处理。
filter与servlet的区别
Filter和servlet都可以对URL进行处理,Filter是一个链式处理,只要你想继续处理就可以传递下去;而Servlet则是一次处理并返回!适合简单逻辑处理。
filter就像”递归”,在web.xml配置中的顺序代表了filter的调用流程,而servlet被调用后不会继续调用其他的servlet!因此配置中的顺序不影响!
filter的生命周期包括:
1、init(FilterConfig config)
2、doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
3、destroy()
Servlet生命周期
web.xml加载顺序(listener>filter>servlet)
总的来说,web.xml的加载顺序是: listener -> filter -> servlet
web项目启动时:
1、读取上下文参数context-param
2、加载监听器listener
3、加载过滤器filter
web项目启动后:
4、第一个请求到来时初始化servlet
如果web.xml中出现了相同的元素,则按照在配置文件中出现的先后顺序来加载。
什么时候创建Servlet?(请求时/启动时)
创建Servlet实例有两个时机:
1、客户端第一次请求某个Servlet时,系统创建该Servlet的实例,大部分Servlet都是这种Servlet。
2、Web应用启动时立即创建Servlet实例,即load-on-start Servlet。
Servlet的生命周期(init>service>destroy)
每个Servlet的运行都遵循如下生命周期:
1、创建Servlet实例,Web容器调用Servlet的init()方法,对Servlet进行初始化。
2、Servlet初始化后,将一直存在于容器中,用于响应客户端请求,如果客户端发送GET请求,容器调用Servlet的doGet()方法处理并响应请求;如果客户端发送POST请求,容器调用Servlet的doPost()方法处理并响应请求。或者统一使用service()方法处理来响应用户请求。
3、Web容器决定销毁Servlet时,先调用Servlet的destory()方法,通常在关闭Web应用时销毁Servlet实例。
init()方法
在Servlet的生命周期中,仅执行一次init()方法,它是在服务器装入Servlet时执行的,可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init();
service()方法
它是Servlet的核心,当一个客户请求改Servlet时,实际的处理工作全部有service方法来完成,service方法用来处理客户端的请求,并生成格式化数据返回给客户端。
每一次请求服务器都会开启一个新的线程并执行一次service方法,service根据客户端的请求类型,调用doGet、doPost等方法。
Service()方法有两个参数:“请求”(ServletRequest)对象和“响应”(ServletResponse)对象,请求到来时会把请求的具体内容传给ServletRequest参数,service()方法处理完后把响应放到ServletResponse对象中。
在Servlet接口的实现类HttpServlet中实现了Service()方法,功能是根据客户端的请求类型(Get/Post/Put/Delete)去调用doGet、doPost等方法。
destroy()方法
仅执行一次,在服务器端停止且卸载Servlet时执行该方法,有点类似于C++的delete方法。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。
该方法在整个生命周期中,也是只会被调用一次,在Servlet对象被销毁是调用,在servlet中,我们可以做一些资源的释放等操作,执行destory方法之后的servlet对象,会等待jvm虚拟机的垃圾回收机制择时回收。
Servlet运行原理以及生命周期
https://www.cnblogs.com/fifiyong/p/6390805.html
Servlet简介及其生命周期详解
https://blog.csdn.net/u013054715/article/details/77888617
servlet是单例的吗?
不同的用户同时对同一个业务(如注册)发出请求,那这个时候容器里产生的有是几个servlet实例呢?
只有一个servlet实例。一个servlet是在第一次被访问时加载到内存并实例化的。同样的业务请求共享一个servlet实例。不同的业务请求一般对应不同的servlet. 想也知道拉,如果一个网站要被几千万人同时登录,如果创建几千万个实例的话服务器还怎么跑得动?
对java servlet 单例模式的理解
http://blog.csdn.net/nieyinyin/article/details/7470576
Servlet 是单例吗 ?
1、servlet是单例的,严格地说是一个servlet-mapping对应一个单例实例(如果一个Servlet被映射了两个URL地址,会生成两个实例)。早期的CGI模式是原型式的,例如同时并发2000次请求一个Servlet,如果不是单例的,内存瞬间要创建2000个对象,同时为了线程安全还得阻塞对方线程,其性能非常之差。
2、要维护Servlet线程安全有很多办法,通常是使用同步块(或方法)来保护共享数据,其次可以volatile、Lock一些锁机制,还可以使用ThreadLocal来打通安全通道,另外还有原子操作也是用来保护数据安全,有非常多的选择。以笔者编程经验来看,Servlet需要考虑数据安全的应用场景不到千分之一。
如何保证servlet的线程安全?
Servlet 默认是单例模式,在web 容器中只创建一个实例,所以多个线程同时访问servlet的时候,Servlet是线程不安全的。
Service方法会在服务器被访问时调用,Servlet对象的生命周期中service方法可能被多次调用,由于web-server启动后,服务器中公开的部分资源将处于网络中,当网络中的不同主机(客户端)并发访问服务器中的同一资源,服务器将开设多个线程处理不同的请求,多线程同时处理同一对象时,有可能出现数据并发访问的错误。
另外注意,多线程难免同时处理同一变量时(如:对同一文件进行写操作),且有读写操作时,必须考虑是否加上同步,同步添加时,不要添加范围过大,有可能使程序变为纯粹的单线程,大大削弱了系统性能;只需要做到多个线程安全的访问相同的对象就可以了。
实现SingleThreadModel接口(已废弃)
1、实现 javax.servlet.SingleThreadModel 接口(已废弃)
该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,Servlet容器通过为每次请求创建一个servlet实例来保证这一点。此接口没有方法,跟Serializable接口一样只是一个标识接口。
singlethreadmodel并不能解决所有的线程安全问题。例如,会话属性和静态变量仍然可以同时通过多线程的多个请求访问。
Servlet 是线程安全的吗?
https://blog.csdn.net/jijianshuai/article/details/77878713
synchronized或Lock锁
2、同步对共享数据的操作
使用synchronized或Lock锁来保证对共享数据的互斥操作。
实例变量改为局部变量
3、实例变量改为局部变量
多线程并不共享局部变量,所以我们要尽可能的在servlet中使用局部变量。
本实例中的线程安全问题是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。
修正上面的Servlet代码,将实例变量改为局部变量可实现同样的功能,也能保证线程安全。
Servlet之单例与线程安全
http://lixh1986.iteye.com/blog/2355692
servlet是单例的 所以需要线程安全 以及如何实现线程安全
https://blog.csdn.net/i_will_try/article/details/62215633
ServletRequest
ServletRequest中getReader()和getInputStream()只能调用一次
想在 Filter 中打印 ServletRequest 到日志,发现总是报错
getInputStream() has already been called for this request
才知道
ServletRequest的getReader()和getInputStream()两个方法只能被调用一次,而且不能两个都调用。
两个方法都注明方法只能被调用一次,由于RequestBody是流的形式读取,那么流读了一次就没有了,所以只能被调用一次。既然是因为流只能读一次的原因,那么只要将流的内容保存下来,就可以实现反复读取了。
ServletRequest中getReader()和getInputStream()只能调用一次的解决办法
https://liwx2000.iteye.com/blog/1542431
java.lang.IllegalStateException: getReader() has already been called for this request
https://stackoverflow.com/questions/7318632/java-lang-illegalstateexception-getreader-has-already-been-called-for-this-re
ServletRequest 源码
package javax.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
/**
* Defines an object to provide client request information to a servlet. The
* servlet container creates a <code>ServletRequest</code> object and passes it
* as an argument to the servlet's <code>service</code> method.
* <p>
* A <code>ServletRequest</code> object provides data including parameter name
* and values, attributes, and an input stream. Interfaces that extend
* <code>ServletRequest</code> can provide additional protocol-specific data
* (for example, HTTP data is provided by
* {@link javax.servlet.http.HttpServletRequest}.
*
* @see javax.servlet.http.HttpServletRequest
*/
public interface ServletRequest {
/**
* Returns the value of the named attribute as an <code>Object</code>, or
* <code>null</code> if no attribute of the given name exists.
* <p>
* Attributes can be set two ways. The servlet container may set attributes
* to make available custom information about a request. For example, for
* requests made using HTTPS, the attribute
* <code>javax.servlet.request.X509Certificate</code> can be used to
* retrieve information on the certificate of the client. Attributes can
* also be set programmatically using {@link ServletRequest#setAttribute}.
* This allows information to be embedded into a request before a
* {@link RequestDispatcher} call.
* <p>
* Attribute names should follow the same conventions as package names.
* Names beginning with <code>java.*</code> and <code>javax.*</code> are
* reserved for use by the Servlet specification. Names beginning with
* <code>sun.*</code>, <code>com.sun.*</code>, <code>oracle.*</code> and
* <code>com.oracle.*</code>) are reserved for use by Oracle Corporation.
*
* @param name
* a <code>String</code> specifying the name of the attribute
* @return an <code>Object</code> containing the value of the attribute, or
* <code>null</code> if the attribute does not exist
*/
public Object getAttribute(String name);
/**
* Returns an <code>Enumeration</code> containing the names of the
* attributes available to this request. This method returns an empty
* <code>Enumeration</code> if the request has no attributes available to
* it.
*
* @return an <code>Enumeration</code> of strings containing the names of the
* request's attributes
*/
public Enumeration<String> getAttributeNames();
/**
* Returns the name of the character encoding used in the body of this
* request. This method returns <code>null</code> if the request does not
* specify a character encoding
*
* @return a <code>String</code> containing the name of the character
* encoding, or <code>null</code> if the request does not specify a
* character encoding
*/
public String getCharacterEncoding();
/**
* Overrides the name of the character encoding used in the body of this
* request. This method must be called prior to reading request parameters
* or reading input using getReader().
*
* @param env
* a <code>String</code> containing the name of the character
* encoding.
* @throws java.io.UnsupportedEncodingException
* if this is not a valid encoding
*/
public void setCharacterEncoding(String env)
throws java.io.UnsupportedEncodingException;
/**
* Returns the length, in bytes, of the request body and made available by
* the input stream, or -1 if the length is not known. For HTTP servlets,
* same as the value of the CGI variable CONTENT_LENGTH.
*
* @return an integer containing the length of the request body or -1 if the
* length is not known or is greater than {@link Integer#MAX_VALUE}
*/
public int getContentLength();
/**
* Returns the length, in bytes, of the request body and made available by
* the input stream, or -1 if the length is not known. For HTTP servlets,
* same as the value of the CGI variable CONTENT_LENGTH.
*
* @return a long integer containing the length of the request body or -1 if
* the length is not known
* @since Servlet 3.1
*/
public long getContentLengthLong();
/**
* Returns the MIME type of the body of the request, or <code>null</code> if
* the type is not known. For HTTP servlets, same as the value of the CGI
* variable CONTENT_TYPE.
*
* @return a <code>String</code> containing the name of the MIME type of the
* request, or null if the type is not known
*/
public String getContentType();
/**
* Retrieves the body of the request as binary data using a
* {@link ServletInputStream}. Either this method or {@link #getReader} may
* be called to read the body, not both.
*
* @return a {@link ServletInputStream} object containing the body of the
* request
* @exception IllegalStateException
* if the {@link #getReader} method has already been called
* for this request
* @exception IOException
* if an input or output exception occurred
*/
public ServletInputStream getInputStream() throws IOException;
/**
* Returns the value of a request parameter as a <code>String</code>, or
* <code>null</code> if the parameter does not exist. Request parameters are
* extra information sent with the request. For HTTP servlets, parameters
* are contained in the query string or posted form data.
* <p>
* You should only use this method when you are sure the parameter has only
* one value. If the parameter might have more than one value, use
* {@link #getParameterValues}.
* <p>
* If you use this method with a multivalued parameter, the value returned
* is equal to the first value in the array returned by
* <code>getParameterValues</code>.
* <p>
* If the parameter data was sent in the request body, such as occurs with
* an HTTP POST request, then reading the body directly via
* {@link #getInputStream} or {@link #getReader} can interfere with the
* execution of this method.
*
* @param name
* a <code>String</code> specifying the name of the parameter
* @return a <code>String</code> representing the single value of the
* parameter
* @see #getParameterValues
*/
public String getParameter(String name);
/**
* Returns an <code>Enumeration</code> of <code>String</code> objects
* containing the names of the parameters contained in this request. If the
* request has no parameters, the method returns an empty
* <code>Enumeration</code>.
*
* @return an <code>Enumeration</code> of <code>String</code> objects, each
* <code>String</code> containing the name of a request parameter;
* or an empty <code>Enumeration</code> if the request has no
* parameters
*/
public Enumeration<String> getParameterNames();
/**
* Returns an array of <code>String</code> objects containing all of the
* values the given request parameter has, or <code>null</code> if the
* parameter does not exist.
* <p>
* If the parameter has a single value, the array has a length of 1.
*
* @param name
* a <code>String</code> containing the name of the parameter
* whose value is requested
* @return an array of <code>String</code> objects containing the parameter's
* values
* @see #getParameter
*/
public String[] getParameterValues(String name);
/**
* Returns a java.util.Map of the parameters of this request. Request
* parameters are extra information sent with the request. For HTTP
* servlets, parameters are contained in the query string or posted form
* data.
*
* @return an immutable java.util.Map containing parameter names as keys and
* parameter values as map values. The keys in the parameter map are
* of type String. The values in the parameter map are of type
* String array.
*/
public Map<String, String[]> getParameterMap();
/**
* Returns the name and version of the protocol the request uses in the form
* <i>protocol/majorVersion.minorVersion</i>, for example, HTTP/1.1. For
* HTTP servlets, the value returned is the same as the value of the CGI
* variable <code>SERVER_PROTOCOL</code>.
*
* @return a <code>String</code> containing the protocol name and version
* number
*/
public String getProtocol();
/**
* Returns the name of the scheme used to make this request, for example,
* <code>http</code>, <code>https</code>, or <code>ftp</code>. Different
* schemes have different rules for constructing URLs, as noted in RFC 1738.
*
* @return a <code>String</code> containing the name of the scheme used to
* make this request
*/
public String getScheme();
/**
* Returns the host name of the server to which the request was sent. It is
* the value of the part before ":" in the <code>Host</code> header value,
* if any, or the resolved server name, or the server IP address.
*
* @return a <code>String</code> containing the name of the server
*/
public String getServerName();
/**
* Returns the port number to which the request was sent. It is the value of
* the part after ":" in the <code>Host</code> header value, if any, or the
* server port where the client connection was accepted on.
*
* @return an integer specifying the port number
*/
public int getServerPort();
/**
* Retrieves the body of the request as character data using a
* <code>BufferedReader</code>. The reader translates the character data
* according to the character encoding used on the body. Either this method
* or {@link #getInputStream} may be called to read the body, not both.
*
* @return a <code>BufferedReader</code> containing the body of the request
* @exception java.io.UnsupportedEncodingException
* if the character set encoding used is not supported and
* the text cannot be decoded
* @exception IllegalStateException
* if {@link #getInputStream} method has been called on this
* request
* @exception IOException
* if an input or output exception occurred
* @see #getInputStream
*/
public BufferedReader getReader() throws IOException;
/**
* Returns the Internet Protocol (IP) address of the client or last proxy
* that sent the request. For HTTP servlets, same as the value of the CGI
* variable <code>REMOTE_ADDR</code>.
*
* @return a <code>String</code> containing the IP address of the client
* that sent the request
*/
public String getRemoteAddr();
/**
* Returns the fully qualified name of the client or the last proxy that
* sent the request. If the engine cannot or chooses not to resolve the
* hostname (to improve performance), this method returns the dotted-string
* form of the IP address. For HTTP servlets, same as the value of the CGI
* variable <code>REMOTE_HOST</code>.
*
* @return a <code>String</code> containing the fully qualified name of the
* client
*/
public String getRemoteHost();
/**
* Stores an attribute in this request. Attributes are reset between
* requests. This method is most often used in conjunction with
* {@link RequestDispatcher}.
* <p>
* Attribute names should follow the same conventions as package names.
* Names beginning with <code>java.*</code> and <code>javax.*</code> are
* reserved for use by the Servlet specification. Names beginning with
* <code>sun.*</code>, <code>com.sun.*</code>, <code>oracle.*</code> and
* <code>com.oracle.*</code>) are reserved for use by Oracle Corporation.
* <br>
* If the object passed in is null, the effect is the same as calling
* {@link #removeAttribute}. <br>
* It is warned that when the request is dispatched from the servlet resides
* in a different web application by <code>RequestDispatcher</code>, the
* object set by this method may not be correctly retrieved in the caller
* servlet.
*
* @param name
* a <code>String</code> specifying the name of the attribute
* @param o
* the <code>Object</code> to be stored
*/
public void setAttribute(String name, Object o);
/**
* Removes an attribute from this request. This method is not generally
* needed as attributes only persist as long as the request is being
* handled.
* <p>
* Attribute names should follow the same conventions as package names.
* Names beginning with <code>java.*</code> and <code>javax.*</code> are
* reserved for use by the Servlet specification. Names beginning with
* <code>sun.*</code>, <code>com.sun.*</code>, <code>oracle.*</code> and
* <code>com.oracle.*</code>) are reserved for use by Oracle Corporation.
*
* @param name
* a <code>String</code> specifying the name of the attribute to
* remove
*/
public void removeAttribute(String name);
/**
* Returns the preferred <code>Locale</code> that the client will accept
* content in, based on the Accept-Language header. If the client request
* doesn't provide an Accept-Language header, this method returns the
* default locale for the server.
*
* @return the preferred <code>Locale</code> for the client
*/
public Locale getLocale();
/**
* Returns an <code>Enumeration</code> of <code>Locale</code> objects
* indicating, in decreasing order starting with the preferred locale, the
* locales that are acceptable to the client based on the Accept-Language
* header. If the client request doesn't provide an Accept-Language header,
* this method returns an <code>Enumeration</code> containing one
* <code>Locale</code>, the default locale for the server.
*
* @return an <code>Enumeration</code> of preferred <code>Locale</code>
* objects for the client
*/
public Enumeration<Locale> getLocales();
/**
* Returns a boolean indicating whether this request was made using a secure
* channel, such as HTTPS.
*
* @return a boolean indicating if the request was made using a secure
* channel
*/
public boolean isSecure();
/**
* Returns a {@link RequestDispatcher} object that acts as a wrapper for the
* resource located at the given path. A <code>RequestDispatcher</code>
* object can be used to forward a request to the resource or to include the
* resource in a response. The resource can be dynamic or static.
* <p>
* The pathname specified may be relative, although it cannot extend outside
* the current servlet context. If the path begins with a "/" it is
* interpreted as relative to the current context root. This method returns
* <code>null</code> if the servlet container cannot return a
* <code>RequestDispatcher</code>.
* <p>
* The difference between this method and
* {@link ServletContext#getRequestDispatcher} is that this method can take
* a relative path.
*
* @param path
* a <code>String</code> specifying the pathname to the resource.
* If it is relative, it must be relative against the current
* servlet.
* @return a <code>RequestDispatcher</code> object that acts as a wrapper for
* the resource at the specified path, or <code>null</code> if the
* servlet container cannot return a <code>RequestDispatcher</code>
* @see RequestDispatcher
* @see ServletContext#getRequestDispatcher
*/
public RequestDispatcher getRequestDispatcher(String path);
/**
* @param path The virtual path to be converted to a real path
* @return {@link ServletContext#getRealPath(String)}
* @deprecated As of Version 2.1 of the Java Servlet API, use
* {@link ServletContext#getRealPath} instead.
*/
@SuppressWarnings("dep-ann")
// Spec API does not use @Deprecated
public String getRealPath(String path);
/**
* Returns the Internet Protocol (IP) source port of the client or last
* proxy that sent the request.
*
* @return an integer specifying the port number
* @since Servlet 2.4
*/
public int getRemotePort();
/**
* Returns the host name of the Internet Protocol (IP) interface on which
* the request was received.
*
* @return a <code>String</code> containing the host name of the IP on which
* the request was received.
* @since Servlet 2.4
*/
public String getLocalName();
/**
* Returns the Internet Protocol (IP) address of the interface on which the
* request was received.
*
* @return a <code>String</code> containing the IP address on which the
* request was received.
* @since Servlet 2.4
*/
public String getLocalAddr();
/**
* Returns the Internet Protocol (IP) port number of the interface on which
* the request was received.
*
* @return an integer specifying the port number
* @since Servlet 2.4
*/
public int getLocalPort();
/**
* @return TODO
* @since Servlet 3.0 TODO SERVLET3 - Add comments
*/
public ServletContext getServletContext();
/**
* @return TODO
* @throws IllegalStateException If async is not supported for this request
* @since Servlet 3.0 TODO SERVLET3 - Add comments
*/
public AsyncContext startAsync() throws IllegalStateException;
/**
* @param servletRequest The ServletRequest with which to initialise the
* asynchronous context
* @param servletResponse The ServletResponse with which to initialise the
* asynchronous context
* @return TODO
* @throws IllegalStateException If async is not supported for this request
* @since Servlet 3.0 TODO SERVLET3 - Add comments
*/
public AsyncContext startAsync(ServletRequest servletRequest,
ServletResponse servletResponse) throws IllegalStateException;
/**
* @return TODO
* @since Servlet 3.0 TODO SERVLET3 - Add comments
*/
public boolean isAsyncStarted();
/**
* @return TODO
* @since Servlet 3.0 TODO SERVLET3 - Add comments
*/
public boolean isAsyncSupported();
/**
* Get the current AsyncContext.
*
* @return The current AsyncContext
*
* @throws IllegalStateException if the request is not in asynchronous mode
* (i.e. @link #isAsyncStarted() is {@code false})
*
* @since Servlet 3.0
*/
public AsyncContext getAsyncContext();
/**
* @return TODO
* @since Servlet 3.0 TODO SERVLET3 - Add comments
*/
public DispatcherType getDispatcherType();
}
上一篇 阿里云ECS使用记录
下一篇 Vue
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: