Servlet
Servlet是Java编写的服务器端程序,可以交互式地浏览和生成数据,生成动态Web内容。一般来说,Servlet是指任何实现了这个Servlet接口的类。
Servlet可在web.xml中配置
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>com.jundeng.ServletTest</servlet-class>
<!--为非负数时服务器时启动创建servlet,默认为第一次访问时创建-->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<!--访问路径-->
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
也可以通过注解配置,通过注解配置的Servlet无需指定名字。
一个Servlet可以指定多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})
,路径定义规则如下:
- /xxx:路径匹配
- /xxx/xxx:多层路径,目录结构
- *.do:扩展名匹配
另外在idea中启动web项目时,有war模式和war exploded模式
-
war:先将项目打成war包,再发布
-
war exploded:直接把文件夹、jsp页面 、classes等等移到Tomcat 部署文件夹里面,进行加载部署
request
HTTP 请求报文由请求行、请求头部、空行 和 请求包体 4 个部分组成, 可以通过request对象获取请求报文信息
其中请求行又包括:请求方式 请求url 请求协议/版本,如GET /login.html HTTP/1.1
另外只有POST请求方式,才有请求包体,在请求体中封装了POST请求的请求参数
获取请求行
// 获取请求方式
String method = req.getMethod();
// 获取虚拟目录,即根目录applicationContext, 如果为/z
String contextPath = req.getContextPath();
// 获取servlet路径
String servletPath = req.getServletPath();
// 获取请求参数
String queryString = req.getQueryString();
// 获取请求uri
String requestURI = req.getRequestURI();
// 获取协议及版本
String protocol = req.getProtocol();
// 获取客户ip
String remoteAddr = req.getRemoteAddr();
获取请求头
// String getHeader(String name):通过请求头的名称获取请求头的值
// Enumeration<String> getHeaderNames():获取所有的请求头名称
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String value = req.getHeader(name);
System.out.println(name + ": " + value);
}
获取请求体(post)
通过获取输入流来获取请求体中的内容
// BufferedReader getReader():获取字符输入流,只能操作字符数据
// ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
BufferedReader reader = req.getReader();
String line = null;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
获取携带参数(get, post)
// 称获取对应key的参数值的数组
String[] values = req.getParameterValues("aba");
for (String value : values) {
System.out.println(value);
}
// 获取所有请求的参数名称
Enumeration<String> parameterNames = req.getParameterNames();
while (parameterNames.hasMoreElements()) {
System.out.println(parameterNames.nextElement());
}
// 获取所有参数的map集合
Map<String, String[]> parameterMap = req.getParameterMap();
Set<String> keys = parameterMap.keySet();
for (String key : keys) {
String[] value = parameterMap.get(key);
System.out.println("---------------");
for (String s : value) {
System.out.println(s);
}
}
请求转发
// 以key-value设置共享数据,只在一次请求中有效
req.setAttribute("user", "jundeng");
// 获取转发器对象进行转发
req.getRequestDispatcher("/request/dispatcher2").forward(req, resp);
// 获取共享数据
req.getAttribute("user");
response
HTTP响应报文由响应行、响应头、空行 和 响应包体 4 个部分组成,可以通过response对象设置响应报文信息。
其中响应行由协议/版本 响应状态码 状态码
描述组成,响应状态码描述了请求的状态,分类如下:
1xx
:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码2xx
:成功。代表:2003xx
:重定向。302代表重定向;304代表访问缓存)4xx
:客户端错误。 404代表请求路径没有对应的资源; 405表示请求方式没有对应的doxxx方法5xx
:服务器端错误。500代表服务器内部出现异常
响应头由key-value组成,常见响应头:
-
Content-Type
:服务器告诉客户端本次响应体数据格式以及编码格式 -
Content-disposition
:服务器告诉客户端以什么格式打开响应体数据,默认为inline
,表示在当前页面内打开;设置为attachment;filename=xxx
表示以附件形式打开响应体,并指定文件名
重定向
可通以下方法重定向
// 设置状态码
resp.setStatus(302);
// 重定向
resp.setHeader("location", "/response/test2");
或
resp.sendRedirect("/response/test2");
重定向(redirect)与转发(forward)的区别:
- 重定向地址栏发生变化,转发不变
- 重定向可以访问其他站点(服务器)的资源,转发只能访问当前服务器下的资源
- 重定向是两次请求,不能使用request对象来共享数据;转发是一次请求,可以使用request对象来共享数据
输出到浏览器
输出内容如果包含中文要指定编码格式:
// 设置输出流编码
resp.setCharacterEncoding("utf-8");
// 通过响应头设置浏览器编码
resp.setHeader("cont-type", "text/html;charset=utf-8");
或通过更简洁的方式设置
resp.setContentType("text/html;charset=utf-8");
通过字符输出
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.write("hello world 你好");
通过字节输出
resp.setContentType("text/html;charset=utf-8");
ServletOutputStream outputStream = resp.getOutputStream();
outputStream.write("你好".getBytes("utf-8"));
ServletContext
可通过request
对象和HttpServlet
对象两种方式获取ServletContext
ServletContext servletContext = this.getServletContext();
ServletContext servletContext = req.getServletContext();
getMimeType
查看文件MIME类型,MIME类型是在互联网通信过程中定义的一种文件数据类型,其格式为:大类型/小类型 => text/html image/jpeg
String file = "1.jpg";
String mimeType = servletContext.getMimeType(file);
System.out.println(mimeType); // image/jpeg
还可通过ServletContext
共享数据,数据在不同请求间也可被访问
setAttribute(String name,Object value)
getAttribute(String name)
removeAttribute(String name)
获取文件在服务器上的路径
String b = servletContext.getRealPath("hello.html");
System.out.println(b); // D:\environment\apache-tomcat-10.1.0-M4\webapps\ROOT\hello.html
String c = servletContext.getRealPath("/WEB-INF/web.xml");
System.out.println(c); // D:\environment\apache-tomcat-10.1.0-M4\webapps\ROOT\WEB-INF\web.xml
String a = servletContext.getRealPath("/WEB-INF/classes/a.txt");
System.out.println(a);// D:\environment\apache-tomcat-10.1.0-M4\webapps\ROOT\WEB-INF\classes\a.txt