tomcat-jsp-servlet
准备
tomcat windows startup.bat shutdown.bat
mac下: startup.sh shutdown.sh
tomcat的运行依赖 JAVA_HOME系统环境变量
tomcat输入地址后 localhost:8080 默认是访问的是ROOT工程
当有工程名时,默认访问index界面
idea 整合 tomcat
创建项目
创建好的web工程
src目录 存放自己编写的java源代码
web目录 专门用来存放web工程的资源文件,比如 html页面、css文件、js文件等等
WEB-INF目录 是一个受服务器保护的目录,浏览器无法访问此目录的内容
WEB-INF/web.xml 它是整个动态web工程的配置描述文件,可以配置很多web工程的组件,比如: servelet程序、filter过滤器、session超时等等
WEB-INF/lib文件夹 用来存放第三方的jar包,IDEA还需要自己配置导入
修改访问路径
Application context是工程路径
更改这里就可以了
修改运行端口号
热部署
Servlet
什么是servlet
- servlet是javaEE规范之一。规范就是接口
- servlet是javaWeb三大组件之一。三大组件就是servlet程序、filter过滤器、listener监听器
- servlet是运行在服务器上的java小程序,他可以接收客户端发过来的请求并相应数据给客户端
手动实现servle程序
- 编写一个类去实现Servlet接口
- 实现service方法、处理请求并相应数据
- 到web.xml配置servlet程序的访问地址
com.kcl.servlet.HelloServlet
点击查看代码
package com.kcl.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServlet 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() {
}
}
web.xml配置servlet
点击查看代码
HelloServlet
com.kcl.servlet.HelloServlet
HelloServlet
/hello
访问
http://localhost:9517/superkcl/hello
servlet生命周期
- 执行servlet构造器方法(自己创建)
- 执行init初始化方法
- 执行servciefangfa
- 执行destroy方法
第一第二步是在创建servlet时被调用
每次调用接口,都会执行service 方法
工程停止时会调用destory方法
HttpservletRequest 继承 ServletRequest
//处理请求并响应
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello servlet被访问了");
HttpServletRequest request = (HttpServletRequest) servletRequest;
String method = request.getMethod();
System.out.println(method);
}
GET
开发时不继承Servlet接口而是其子类HttpServlet方式实现
public class HelloServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doGet(req, resp);
System.out.println("helloservlet 2 doGet方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.doPost(req, resp);
System.out.println("helloservlet 2 doPost方法");
}
}
使用idea创建servlet程序
在包目录下点击右键 new->Create new Servlet
配置一下ServletMapping即可
Servlet类继承体系
servlet实现类: GenericServlet实现servlet接口,对servlet接口做了很多空实现
并持有一个ServletConfig类的引用。并对ServletConfig的使用做一些方法。
HttpServlet继承GenericServlet类
HttpServlet是抽象类,主要实现service方法
实现servcie方法,和我们的理解差不多 req.getMethod();
doGet() doPost()负责抛异常
ServletConfig类
三大作用
- 可以获取servlet程序的别名servlet-name的值
- 获取初始化参数init-param
- 获取servletContext对象
HelloServlet
com.kcl.servlet.HelloServlet
username
root
url
jdbc:mysql://localhost:3306/test
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init");
//1. 可以获取servlet程序的别名servlet-name的值
System.out.println(servletConfig.getServletName());
//2. 获取初始化参数init-param
System.out.println(servletConfig.getInitParameter("username"));
System.out.println(servletConfig.getInitParameter("url"));
//3. 获取servletContext对象
System.out.println(servletConfig.getServletContext());
}
servlet程序默认是第一次访问的时候创建,servletConfig是每个servlet程序创建时,就创建一个对应的servletConfig对象
继承HttpServlet也可以
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig servletConfig = this.getServletConfig();
String servletName = servletConfig.getServletName();
System.out.println(servletName);
}
ServletContext类
- servletContext是一个接口,表示servlet上下文对象
- 一个web工程只有一个servletContext对象实例!!!
- ServletContext对象是一个域对象
域对象,是可以像Map一样存取数据的对象,叫域对象
这里的域指的是存取数据的操作范围
--- 存数据 取数据 删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute()
ServletContext类的四个作用
- 获取web.xml中配置的上下文参数context-param
- 获取当前的工程路径,格式: /工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像map一样存取数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取web.xml中配置的上下文参数context-param
ServletContext servletContext = getServletContext();
System.out.println("username" + servletContext.getInitParameter("username"));
System.out.println(servletContext.getInitParameter("password"));
//2. 获取当前的工程路径,格式: /工程路径
System.out.println(servletContext.getContextPath()); // /superkcl
//3. 获取工程部署后在服务器硬盘上的绝对路径
System.out.println(servletContext.getRealPath("/")); //斜杠解析为:http://ip:port/工程名/
// D:\编程软件\idea2020.1.2\myFile\testTomcat04\out\artifacts\testTomcat04_war_exploded\
//映射到web目录
System.out.println(servletContext.getRealPath("/css"));
//D:\编程软件\idea2020.1.2\myFile\testTomcat04\out\artifacts\testTomcat04_war_exploded\css
//4. 像map一样存取数据
servletContext.setAttribute("key01","value01");
System.out.println(servletContext.getAttribute("key01"));
}
不同servlet中只要存储了,都可以取到的
在web项目停止后才会销毁。
HttpServletRequet
public interface HttpServletRequest extends ServletRequest
ServletRequest也是一个接口
常用方法
getRequestURI() 获取请求资源路径
getRequestURL() 获取绝对路径
getRemoteHost() 获取客户端ip地址
getHeader() 获取请求头
getParameter() 获取请求的参数
getParameterValues() 获取请求的参数(多个值的时候使用)
getMethod() 获取请求的方式GET或POST
setAttribute(key,val) 设置域数据
getAttribute(key) 获取域数据
getRequestDispatcher() 获取请求转发对象
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//getRequestURI() 获取请求资源路径
//URI => /superkcl/contextServlet
System.out.println("URI => "+ request.getRequestURI());
//getRequestURL() 获取绝对路径
//URL => http://localhost:9517/superkcl/contextServlet
System.out.println("URL => "+request.getRequestURL());
//getRemoteHost() 获取客户端ip地址
//RemoteHost => 0:0:0:0:0:0:0:1
System.out.println("RemoteHost => "+ request.getRemoteHost());
//getHeader() 获取请求头
//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
System.out.println(request.getHeader("User-Agent"));
//getParameter() 获取请求的参数
String username = request.getParameter("username");
System.out.println("username => " + username);
String password = request.getParameter("password");
System.out.println("password => " + password);
String[] hobby = request.getParameterValues("hobby");
System.out.println("hobby => " + Arrays.asList(hobby));
//getParameterValues() 获取请求的参数(多个值的时候使用)
//getMethod() 获取请求的方式GET或POST
//请求的方式 => GET
System.out.println("请求的方式 => " + request.getMethod());
//setAttribute(key,val) 设置域数据
//getAttribute(key) 获取域数据
//getRequestDispatcher() 获取请求转发对象
}
//getParameter() 获取请求的参数
String username = request.getParameter("username");
System.out.println("username => " + username);
String password = request.getParameter("password");
System.out.println("password => " + password);
String[] hobby = request.getParameterValues("hobby");
System.out.println("hobby => " + Arrays.asList(hobby));
post请求也是同样的道理
post请求会出现中文乱码
request.setCharacterEncoding("UTF-8");
在获取请求参数之前调用才有效
get请求不会出现中文乱码
请求转发
服务器接收到请求后,从一个资源跳转到另一个资源的操作叫请求转发
......
req.setAttribute只在请求域中有效
servlet1
RequsetDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2")
requestDispatcher.forward(req,resp)
servlet2
处理自己的业务
特点:
1.浏览器地址栏没有变化
2.他们是一次请求
3.他们共享Request域中的数据
4.可以转发到WEB-INF目录下
浏览器是反问不到WEB-INF目录的
dispatcher可以访问到!"/WEB-INF/form.html"
5.是否可以访问到项目以外的网址? 不可以! 默认是访问当前项目下
base标签作用
/的不同含义
- 如果被浏览器解析 a标签 得到的地址就是 http://ip:port/
- 如果被服务器解析,得到的地址就是 http://ip:port/工程路径
/servlet
servletContext.getRealPath("/")
request.getRequestDispatcher("/")
特殊情况:
response.sendRediect("/")
请求重定向,把斜杠发送给浏览器解析。得到http://ip:port
HttpServletResponse
类似于HttpServletRequst,每次请求进来,都会创建一个response对象传递给servlet使用
两个流
字节流-getOutputStream();常用于下载,传递二进制数据
字符流 getWriter() 常用于回传字符串(常用)
两个流只能使用一个
使用了字节流,就不能再使用字符流,否则就会报错
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
ServletOutputStream outputStream = resp.getOutputStream();
//error
}
}
字符流
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("response kcl");
}
but写中文会乱码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("UTF-8");
//通过响应头,设置浏览器也是用UTF-8
resp.setHeader("Content-Type","text/html; charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("response kcl 寇春雷");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//一行代码同时设置服务器和客户端都使用UTF-8
resp.setContentType("text/html; charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("response kcl 寇春雷");
}
请求重定向
客户端请求服务器,服务器返回一个新地址,旧地址废弃
1.浏览器地址栏会发生变化
2.两次请求
3.不共享request域中的数据
4.不能访问WEB-INF下的资源
5.可以重定向至其他网站
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应状态码302,表示重定向
resp.setStatus(302);
//设置响应头设置新的地址在哪里
resp.setHeader("Location","http://localhost:9517/superkcl/hello"); //绝对地址
}
另外一种方法
resp.sendRedirect("http://localhost:9517/superkcl/hello");