个人主页:Hello Code.
本文专栏:《Java WEB从入门到实战》
Java WEB完整内容请点击前往Java WEB从入门到实战 查看
如有问题,欢迎指正,一起学习~~
关系视图
出生对应的是
init
方法
活着对应的是service
方法(doGet
和doPost
方法)
死亡对应的是destroy
方法
结论: Servlet对象只会创建一次,销毁一次。所以Servlet对象只有一个实例。如果一个对象实例在应用中是唯一的存在,那么就称他为单例模式
结论: 一个浏览器代表一个线程,多个浏览器代表多个线程。按理说应该是每个浏览器查看的都是自己的信息。但结果浏览器中数据混乱。因此,我们可以认为Servlet是线程不安全的!
解决: 定义类成员要谨慎。如果是共用的,并且只会在初始化时赋值,其它时间都是获取的话,那么是没问题的。如果不是共用的,或者每次使用都有可能对其赋值,那就要考虑线程安全的问题了,可以将其定义到doGet或doPost方法内或者使用同步功能即可
具体名称的方式。访问的资源路径必须和映射配置完全相同 【常用】
<servlet>
<servlet-name>Demoservlet-name>
<servlet-class>study.servlet.Demoservlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demoservlet-name>
<url-pattern>/Demourl-pattern>
servlet-mapping>
/
开头 + 通配符的方式。只要符合目录结构即可,不用考虑结尾是什么
<servlet>
<servlet-name>Demo2servlet-name>
<servlet-class>study.servlet.Demo2servlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demo2servlet-name>
<url-pattern>/Demo2/*url-pattern>
servlet-mapping>
通配符 + 固定格式结尾的方式。只要符合固定结尾格式即可,不用考虑前面的路径
<servlet>
<servlet-name>Demo2servlet-name>
<servlet-class>study.servlet.Demo2servlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demo2servlet-name>
<url-pattern>*.testurl-pattern>
servlet-mapping>
注意: 优先级问题。越是具体的优先级越高,越是模糊的 优先级越低。第一种 > 第二种 > 第三种
多路径映射
/
+ 通配符)package study.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class Demo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取浏览器路径
String requestURI = req.getRequestURI();
// 分隔路径
String path = requestURI.substring(requestURI.lastIndexOf("/"));
// 路径判断,区分价格
if(path.equals("/vip")){
System.out.println("100元");
}else if(path.equals("/vvip")){
System.out.println("200元");
}else System.out.println("300元");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
标签中,添加
标签1
默认Servlet是由服务器提供的一个Servlet。它配置在 Tomcat 的 conf 目录中的 web.xml 中
/
。
标签中,通过
标签来配置。有两个子标签
:代表初始化参数的key
:代表初始化参数的value<servlet>
<servlet-name>servletConfigDemoservlet-name>
<servlet-class>study.servlet.servletConfigDemoservlet-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>descparam-name>
<param-value>This is ServletConfigparam-value>
init-param>
servlet>
返回值 | 方法名 | 说明 |
---|---|---|
String | getInitParameter(String name) | 根据参数名称获取参数的值 |
Enumeration | getInitParameterNames() | 获取所有参数名称的枚举 |
String | getServletName() | 获取Servlet的名称 |
ServletContext | getServletContext() | 获取ServletContext对象 |
private ServletConfig config;
public void init(ServletConfig config) throws ServletException{
this.config = config;
}
Enumeration<String> keys = config.getInitParameterNames();
while(keys.hasMoreElements()){
String key = keys.nextElement();
String value = config.getInitParameter(key);
System.out.println(key + "--" + value);
}
// ServletConfigDemo测试代码
package study.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
public class ServletConfigDemo extends HttpServlet {
private ServletConfig config;
// 通过init方法对config赋值,获取ServletConfig对象
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 根据name获取value
String encoding = config.getInitParameter("encoding");
System.out.println("encoding:" + encoding);
// 获取所有name并遍历
Enumeration<String> names = config.getInitParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
String value = config.getInitParameter(name);
System.out.println(name + "---" + value);
}
// 获取Servlet-name
String sname = config.getServletName();
System.out.println("Servlet-name:" + sname);
// 获取ServletContext对象
ServletContext servletContext = config.getServletContext();
System.out.println(servletContext);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
标签中,通过
标签来配置。有两个子标签
:代表全局初始化参数的key
:代表全局初始化参数的value<context-param>
<param-name>globalencodingparam-name>
<param-value>UTF-8param-value>
context-param>
<context-param>
<param-name>globaldescparam-name>
<param-value>This is ServletContextparam-value>
context-param>
返回值 | 方法名 | 说明 |
---|---|---|
String | getInitParameter(String name) | 根据名称获取全局配置的参数 |
String | getContextPath() | 获取当前应用的访问虚拟目录 |
String | getRealPath(String path) | 根据虚拟目录获取应用部署的磁盘绝对路径 |
HttpServlet
类继承自GenericServlet
类
GenericServlet
类中有getServletContext
方法,可以直接获取ServletContext
对象
返回值 | 方法名 | 说明 |
---|---|---|
void | setAttribute(String name, Object value) | 向应用域对象中存储数据 |
Object | getAttribute(String name) | 通过名称获取应用域对象中的数据 |
void | removeAttribute(String name) | 通过名称移除应用域对象中的数据 |
package study.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
public class ServletContextDemo extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = req.getServletContext();
Enumeration<String> names = servletContext.getInitParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
String value = servletContext.getInitParameter(name);
System.out.println(name + "====" + value);
}
resp.setContentType("text/html;charset=UTF-8");
String contextPath = servletContext.getContextPath();
String realPath = servletContext.getRealPath(contextPath);
PrintWriter pw = resp.getWriter();
pw.write("虚拟目录为:" + contextPath + "
");
pw.write("真实目录为:" + realPath);
servletContext.setAttribute("use","lisi");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
Servlet3.0 规范
实现步骤
@WebServlet("/servletDemo")
public class ServletDemo extends HttpServlet{
}
步骤
定义一个类,继承HttpServlet
重写 doGet 和 doPost方法
定义一个类,实现ServletContainerInitializer接口
在src 目录下创建一个META-INF的包
在 META-INF 包下创建一个services 的包
在 services 包下创建一个 javax.servlet.ServletContainerInitializer 的文件
文件中的内容为容器实现类的全类名
在容器实现类中的 onStartup 方法中完成注册 Servlet
public void onStartup(Set<Class<?>> set, ServletContext servletContext){
// 1.创建ServletDemo类的对象
ServletDemo servletDemo = new ServletDemo();
// 2. 在ServletContext 对象中添加Servlet,并得到Servlet的动态配置对象
ServletRegistration.Dynamic registration = servletContext.addServlet("ServletDemo", servletDemo);
// 3. 配置Servlet
registration.addMapping("/servletDemo"); // 映射访问资源的路径
registration.setLoadOnStartup(1); // 设置Servlet加载时机
}
部署并启动项目
通过浏览器测试
步骤
获取表单数据
req.getParameter(name值)
:就可以通过HttpServletRequest 对象中的方法 通过表单的name属性获取到对应的表单数据响应数据
PrintWriter pw = resp.getWriter()
:通过 HttpServletResponse 对象中的方法获取输出流对象
pw.println("Save Success")
:将指定内容响应到浏览器中
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加学生title>
head>
<body>
<form action="/add" method="get">
姓名:<input type="text" name="username"> <br>
年龄:<input type="number" name="age"> <br>
成绩:<input type="number" name="score"> <br>
<button type="submit">添加button>
form>
body>
html>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>/studentAdd.htmlwelcome-file>
welcome-file-list>
<servlet>
<servlet-name>StudentServletservlet-name>
<servlet-class>studentServlet.addservlet-class>
servlet>
<servlet-mapping>
<servlet-name>StudentServletservlet-name>
<url-pattern>/addurl-pattern>
servlet-mapping>
web-app>
// add.java
package studentServlet;
import studentServlet.bean.Student;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class add extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取对应表单内容
String username = req.getParameter("username");
String age = req.getParameter("age");
String score = req.getParameter("score");
// 封装学生对象
Student stu = new Student(username, Integer.parseInt(age), Integer.parseInt(score));
// 保存到本地文件
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\Java\\code\\StudentServlet\\stu.txt",true));
bw.write(stu.getUsername() + "," + stu.getAge() + "," + stu.getScore());
bw.newLine();
bw.close();
// 响应给浏览器
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
pw.println("添加成功,将在3秒后跳转到首页!!!");
resp.setHeader("Refresh","3;url=/index.html");
pw.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
推荐阅读:【Java WEB】请求对象&响应对象