Servlet
Java
↓
MySql
↓
jdbc
↓
Tomcat
↓
Servlet
↓
html
css
javascript
javascriptDOM操作
vue
react
简介
静态资源
无需在程序运行时通过代码运行生成的资源,在程序运行之前就写好的资源. 例如:html css js img ,音频文件和视频文件
动态资源
需要在程序运行时通过代码运行生成的资源,在程序运行之前无法确定的数据,运行时动态生成。例如Servlet,Thymeleaf …
动态资源指的不是视图上的动画效果或者是简单的人机交互效果
去蛋糕店买蛋糕
- 直接买柜台上已经做好的 : 静态资源
- 和柜员说要求后现场制作 : 动态资源
Servlet (server applet) 是运行在服务端(tomcat)的Java小程序,是sun公司提供一套定义动态资源规范; 从代码层面上来讲Servlet就是一个接口
用来接收、处理客户端请求、响应给浏览器的动态资源。在整个Web应用中,Servlet主要负责接收处理请求、协同调度功能以及响应数据。我们可以把Servlet称为Web应用中的控制器
- 不是所有的JAVA类都能用于处理客户端请求,能处理客户端请求并做出响应的一套技术标准就是Servlet
- Servlet是运行在服务端的,所以 Servlet必须在WEB项目中开发且在Tomcat这样的服务容器中运行
请求响应与HttpServletRequest和HttpServletResponse之间的对应关系
开发过程
搭建开发环境
从tomcat安装目录下找到lib,然后将servlet-api.jar配置到环境变量classpath中
当然还有别的方法
部署servlet
直接使用tomcat的webapps
创建一个servlet-test文件夹
目录结构:(模仿其他项目的结构,大致也和idea创建的目录相同)
static代表静态资源,像img js css直接放到这里即可,或者创建文件夹方便管理,另外需要一个index.html作为主页
WEB-INF内如下图,web.xml直接复制现成的即可
编写一个 “ .java ” 文件
import jakarta.servlet.*;
import java.io.IOException;
public class MyServlet implements Servlet {
public void init(ServletConfig config) throws ServletException {
}
public void service(ServletRequest request , ServletResponse response) throws ServletException , IOException {
System.out.println("My First Servlet!");
}
public void destroy(){}
public ServletConfig getServletConfig(){
return null;
}
public String getServletInfo(){
return null;
}
}
将该“ .java ”文件放置到classes文件夹内。并且使用javac将其编译。
配置关联该类文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<servlet>
<!--给UserServlet起一个别名-->
<servlet-name>userServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--关联别名和映射路径-->
<servlet-name>userServlet</servlet-name>
<!--可以为一个Servlet匹配多个不同的映射路径,但是不同的Servlet不能使用相同的url-pattern-->
<url-pattern>/</url-pattern>
<!-- <url-pattern>/servlet</url-pattern>-->
<!--
/*
/ 表示通配所有资源,不包括jsp文件
/* 表示通配所有资源,包括jsp文件
/a/* 匹配所有以a前缀的映射路径
*.action 匹配所有以action为后缀的映射路径
-->
*/
</servlet-mapping>
</web-app>
启动tomcat
填入url
查看终端输出
看到这段就代表你成功了!(java文件使用idea编写,至于导包问题,就根据idea的快捷方式操作即可,然后单独拿出来放到webapps/classes即可)
一定要注意的是,当你的上个tomcat没有关闭时,再打开一个也会闪一下就关闭,记得关闭上一个。
打war包
默认是开发版(exploded),这种方式是热部署(代码随时发生改变),他不会主动的将class文件与WEB-INF进行关联。
war包的好处在于,可以直接放入tomcat的webapps目录中,启动tomcat后自动解压,即可访问。
发布形式,Artifacts
点击apply
打war包
点击war格式
放到webapps目录下,以后项目写到一个固定版本再次打war包放到此目录
运行tomcat后,tomcat会自动做一个解压操作
Servlet
GenericServlet
该类是一个抽象类,他对除了必要的方法做了初始化,将service声明为抽象方法,使用GenericServlet就可简写。
// 这是实现Servlet类
public class MyServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello Servlet!");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
//这是继承GenericServlet类
public class MyServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello Servlet!");
}
}
HttpServlet
HttpServlet在底层根据请求方式,分配对应的执行方法,是推荐的一种Servlet实现方式
HttpServlet类集成了GenericServlet,所以一般情况下也不需要在意除service外的方法重写
web.xml配置
前面我们讲过web.xml配置文件的基本使用方法,这里我们追加一下load-on-startup 和 注解配置的方法。
load-on-startup
1、元素标记容器足否应该在web应用程序启动的时候就加载这个servlet(如果没有该标记,那么只有被请求时才会执行)(注意是执行init函数,而不是service)。
2、它的值必须是一个整数,表示servlet被加载的先后顺序
3、如果该元素的值为负数或者没有设置,则容器会当Servlet被请求时再加载。
4、如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载,值相同时,容器就会自己选择顺序来加载。
如果只有一个servlet标签添加了load-on-startup这个标记,不管值的大小,那么这个servlet都会被优先执行
注解方式
这种方式是servlet3.0才支持的
//name:设置别名
//value:配置url路径,可以配置多个,一个的话格式 value = "/xxx"
//urlPatterns = {"/bs","/bss"},与value用法一致
//loodOnstartup:配置Servlet的创建时机,如果是0或者证书,启动程序是创建,如果是负数,则访问时创建,数越小优先级越高,通上
@WebServlet(name = "bs",value = {"/bs","/bss"})
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get请求");
}
}
同时配置了注解和web.xml,是不影响的,可以同时生效
request对象
get和post的区别
get请求
get提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连
get方式明文传递,数据量小,不安全
效率高,浏览器默认请求方式为GET请求
对应的Servlet的方法是doGet
post请求
post方法是把提交的数据放在HTTP包的Body中
密文传递数据,数据量大,安全
效率相对没有GET高
对应的Servlet的户法是doPost
get请求
@WebServlet(value = "/my/reg")
public class MyServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("提交内容:"+username+"\n"+password);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/reg">
账号:<input type="text" name="username" id="">
密码:<input type="text" name="password" id="">
<input type="submit" value="注册">
</form>
</body>
</html>
post请求
@WebServlet(value = "/reg")
public class MyServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决中文乱码问题,低版本的tomcat需要,高版本不需要
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("提交内容:"+username+"\n"+password);
}
}
获取请求行
(请求行数据)
1、获取请求方式
String getMethod()
2、获取虚拟目录
String getContextPath()
3、获取Servlet路径
String getServletPath()
4、获取get方式请求参数
String getQueryString()
5、获取请求URL
String getRequestURL()
StringBuffer getRequestURL() ----全路径
6、获取协议及版本
String getProtocol()
7、获取客户机的IP地址
String getRemoteAddr()
获取请求头
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
String value = req.getHeader(name); //常用
System.out.println(name+"==="+value);
}
判断浏览器
String agent =req.getHeader("user-agent");//判断agent的浏览器版本
System.out.println("浏览器"+agent);
获取路径信息(防止盗链)
String referer = req.getHeader("referer");
System.out.println(referer);
if (referer != null) {
if (referer.contains("/my")) {
resp.getWriter().write("播放电影...");
}else {
resp.getWriter().write("VIP才能看哦!");
}
}
请求体
第一步获取流对象(分为字节流和字符流,字符流为普通文本信息,字节流为视频和图片)
BufferedReader getReader()
ServletInputStream getInputStream()
第二部读取数据
reader.readLine()
// 获取字符流
BufferedReader reader = req.getReader();
System.out.println("请求了");
// 读取数据
String line = null;
while ((line = reader.readLine()) != null){
System.out.println(line);
}
其他(常用)
1、获取请求参数(通用方式)
String getParameter(String name); 根据参数名获取值
String[] getParameterValues(String name); 根据参数名获取参数值的数组(例如参数为hobby=xx&hobby=game 多用于复选框)
Enumeration getParameterNames(); 获取所有请求的参数名称
Map<String,String[]> getParameterMap(); 获取所有参数的map集合
2、请求转发
浏览器url不改变,转发只能转发服务器内容资源,并且只发送一次请求,但是结果是多个
req.getRequestDispatcher(“/xxx”).forward(req,resp);
3、共享数据
一个有范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
下面方法request对象的方法
setAttribute(string name,object obj):存储数据
object getAttitude(string name):通过键获取值
removeAttribute(string name):通过键移除键值对
4、获取ServletContext
ServletContext servletContext = req.getServletContext();
response
常用方法
setHeader(name,value) 设置响应信息头
setContentType(String) 设置响应文件类型、响应式的编码格式
setCharacterEncoding(String) 设置服务端响应内容编码格式
getWriter() 获取字符输出流
@WebServlet(value = "/reg")
public class MyServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setHeader("Content-type","text/html;charset=UTF-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("提交内容:"+username+"\n"+password);
PrintWriter printWriter = resp.getWriter();
printWriter.println("注册啦!");
}
}
在这里给客户端发中文时,会乱码
所以需要这段来配置客户端的解码方式resp.setHeader(“Context-type”,“text/html;charset=UTF-8”);
resp.setContentType(“text/html;charset=UTF-8”);这句可以同时设置客户端和服务端的编码格式