Servlet接口基础
Servlet是Java Web开发的核心技术,它定义了一种规范,用于扩展服务器的功能,能够响应客户端请求并生成动态内容,Servlet接口位于javax.servlet包中,核心方法包括service()、doGet()、doPost()等,其中service()是入口方法,由Servlet容器(如Tomcat)调用,用于处理客户端请求并返回响应,要实现Servlet接口,通常有两种方式:直接实现Servlet接口,或继承HttpServlet类(更常用,HttpServlet封装了HTTP协议相关的处理逻辑)。

创建Servlet后,需要在Web应用中配置其访问路径,传统方式是通过web.xml文件配置<servlet>和<servlet-mapping>标签,指定Servlet名称和对应的URL模式;现代开发则更多使用注解@WebServlet,通过urlPatterns属性直接映射访问路径,例如@WebServlet("/hello")表示通过/hello路径可访问该Servlet。
客户端HTTP调用Servlet
客户端调用Servlet主要通过HTTP协议实现,常见方式包括浏览器直接访问、表单提交和AJAX异步请求。
浏览器直接访问
在浏览器地址栏输入Servlet的URL路径(格式为http://域名:端口/应用名/Servlet路径),例如http://localhost:8080/myapp/hello,服务器会解析路径并调用对应的Servlet,若Servlet未处理GET请求,可能返回405错误(Method Not Allowed),需在Servlet中重写doGet()方法。
表单提交
HTML表单通过method属性指定请求方法(GET/POST),action属性指向Servlet路径。
<form action="/myapp/login" method="post">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="登录">
</form>
提交后,浏览器会向/login路径发送POST请求,Servlet通过request.getParameter("username")获取表单数据。
AJAX异步调用
前端通过JavaScript的XMLHttpRequest或Fetch API发送HTTP请求,调用Servlet并处理响应,例如使用Fetch API:
fetch('/myapp/api/data', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({key: 'value'})
})
.then(response => response.json())
.then(data => console.log(data));
Servlet中需设置响应头response.setContentType("application/json"),并通过response.getWriter().write()返回JSON数据。
服务端Java代码调用Servlet
在服务端,Java程序(如另一个Servlet或工具类)调用Servlet接口主要有两种方式:直接调用Servlet方法或通过RequestDispatcher调度。

直接调用Servlet方法(不推荐)
可通过反射或直接实例化Servlet对象并调用其方法,但这种方式会绕过Servlet容器,导致Servlet的生命周期方法(如init()、service())不被正确执行,可能引发线程安全问题(Servlet容器默认以单例模式管理Servlet实例),除非特殊场景,否则不建议直接调用。
使用RequestDispatcher调度(推荐)
RequestDispatcher是Servlet容器提供的对象,用于在服务器端转发或包含请求,能够正确处理Servlet的生命周期和请求/响应对象。
-
请求转发(forward):将当前请求转发到目标Servlet,目标Servlet处理完成后,响应结果直接返回给客户端,客户端浏览器地址栏URL不变。
RequestDispatcher dispatcher = request.getRequestDispatcher("/targetServlet"); dispatcher.forward(request, response);适合多个Servlet协同处理同一请求的场景,如控制器转发到业务逻辑层。
-
请求包含(include):将目标Servlet的响应内容包含到当前Servlet的响应中,目标Servlet执行完成后,控制权返回给当前Servlet。
RequestDispatcher dispatcher = request.getRequestDispatcher("/header"); dispatcher.include(request, response);适合复用公共组件,如页面头部、尾部等。
获取RequestDispatcher的方式有两种:通过request.getRequestDispatcher()(相对路径)或ServletContext.getRequestDispatcher()(绝对路径,以开头,表示从应用根目录开始)。
参数传递与处理
调用Servlet时,参数传递需根据请求类型选择合适的方式。

-
客户端传参:GET请求参数通过URL拼接(
?key1=value1&key2=value2),Servlet通过request.getParameter()获取;POST请求参数在请求体中,需设置request.setCharacterEncoding("UTF-8")(防止中文乱码)后通过request.getParameter()获取。 -
服务端传参:通过
request.setAttribute(key, value)设置请求属性,目标Servlet通过request.getAttribute(key)获取,适合对象类型参数(如List、Map)。// 源Servlet request.setAttribute("user", new User("张三")); dispatcher.forward(request, response); // 目标Servlet User user = (User) request.getAttribute("user");
常见问题与解决方案
-
404错误(Servlet未找到):检查
@WebServlet的urlPatterns或web.xml中的URL映射是否正确,确保路径大小写敏感(Tomcat默认区分大小写)。 -
500错误(服务器内部错误):通常为代码异常,如空指针、类型不匹配,可通过查看Tomcat日志定位异常位置,或在Servlet中添加try-catch块捕获异常并返回友好提示。
-
中文乱码:GET请求乱码需手动解码(
new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8"));POST请求乱码需在获取参数前设置request.setCharacterEncoding("UTF-8"),或通过过滤器统一处理(推荐)。 -
线程安全问题:Servlet是单例多线程访问,避免在Servlet类中使用成员变量存储请求相关数据(如用户信息),应使用局部变量或ThreadLocal。
调用Servlet接口是Java Web开发的基础操作,客户端通过HTTP请求直接访问,服务端则推荐使用RequestDispatcher进行请求调度,开发时需注意配置正确性、参数传递方式、编码处理及线程安全问题,确保Servlet能够稳定、高效地处理请求并返回响应,虽然现代框架(如Spring MVC)简化了Servlet调用流程,但理解Servlet底层原理仍是掌握Java Web开发的关键。












