创建一个Servlet类
A Servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
javax.servlet.Servlet是一个接口。抽象类javax.servlet.GenericServlet实现了它,这是一个与协议无关的Servlet抽象类。我们要讨论的主要是javax.servlet.http.HttpServlet,这个类继承了GenericServlet实现了其service抽象方法用来处理HTTP请求,最后针对不同的HTTP方法调用doGet,doPost等一系列方法。自定义Servlet时,继承HttpServlet,然后重写doXXX方法。
在Web容器中,一个Servlet只有一个实例,如果Servlet配置为容器启动时加载,那么在Web容器启动时加载,并且会调用其init方法,否则init在Servlet第一次被请求时调用。当Web容器关闭时,调用destroy方法。这两个方法都在Servlet接口中进行了定义。要注意的是init方法其实有个参数javax.servlet.ServletConfig,不过GenericServlet实现了该方法并调用了无参数的init方法。init方法的调用发生在Servlet构造方法之后,在能进行响应请求之前,该方法中适合用于初始化数据库之类的操作。准确的说,只有在init方法调用之后,Servlet才是一个真正的Servlet,ServletConfig和javax.servlet.ServletContext对象都已经准备完毕。
public class HelloServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.getWriter().println("Hello, World!");
}
}
在部署描述文件中配置Servlet
部署描述文件就是位于WEB-INF目录中web.xml,在该文件中放置应用程序中所有的listeners,servlets和filters。类似于Android应用程序中的AndroidManifest.xml清单文件。
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.wrox.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
load-on-startup
使得Servlet在容器启动时加载并调用其init方法。标签中的数字表示启动顺序的优先级,数字越小越优先。
映射URL到Servlet
可以映射多个URL到一个Servlet
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/greeting</url-pattern>
<url-pattern>/salutation</url-pattern>
<url-pattern>/wazzup</url-pattern>
</servlet-mapping>
使用注解
@WebServlet(
name = "helloServlet",
urlPatterns = {"/greeting", "/salutation", "/wazzup"},
loadOnStartup = 1
)
public class HelloServlet extends HttpServlet
{
}
接收query参数和post参数
String user = request.getParameter("user");
在使用该方法接收了post参数(位于请求体中)后,不能再调用request的getInputStream或者getReader,否则发生异常。有的参数有多个值,比如复选框。如下获取。
String[] array = request.getParameterValues("color");
使用init参数配置应用
使用Context init参数
这些参数只能在部署描述文件中定义。
<context-param>
<param-name>settingOne</param-name>
<param-value>foo</param-value>
</context-param>
<context-param>
<param-name>settingTwo</param-name>
<param-value>bar</param-value>
</context-param>
被所有Servlet公有,Servlet中这样使用:
ServletContext c = this.getServletContext();
c.getInitParameter("settingOne");
使用Servlet init参数
在部署描述文件中定义Servet的init参数
<servlet>
<servlet-name>servletParameterServlet</servlet-name>
<servlet-class>com.wrox.ServletParameterServlet</servlet-class>
<init-param>
<param-name>database</param-name>
<param-value>CustomerSupport</param-value>
</init-param>
<init-param>
<param-name>server</param-name>
<param-value>10.0.12.5</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servletParameterServlet</servlet-name>
<url-pattern>/servletParameters</url-pattern>
</servlet-mapping>
在注解中配置
@WebServlet(
name = "servletParameterServlet",
urlPatterns = {"/servletParameters"},
initParams = {
@WebInitParam(name = "database", value = "CustomerSupport"),
@WebInitParam(name = "server", value = "10.0.12.5")
}
)
public class ServletParameterServlet extends HttpServlet
{
}
使用Form上传文件
在Servlet上添加注解
文件小于fileSizeThreshold则存在内存中
maxFileSize为能上传的最大文件
maxRequestSize为能接收的Request的最大大小,不管文件多大。
@MultipartConfig(
fileSizeThreshold = 5_242_880, //5MB
maxFileSize = 20_971_520L, //20MB
maxRequestSize = 41_943_040L //40MB
)
假设html中文件上传控件如此定义
<input type="file" name="file1"/>
Servlet中如此处理Request
Part filePart = request.getPart("file1");
InputStream inputStream = filePart.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int read;
final byte[] bytes = new byte[1024];
while((read = inputStream.read(bytes)) != -1)
{
outputStream.write(bytes, 0, read);
}
//获取上传时的原文件名
filePart.getSubmittedFileName();
outputStream.toByteArray();