使用工具:IDEA、tomcat、maven
新建一个maven项目。在maven项目中导入servlet依赖
javax.servlet javax.servlet-api4.0.1
新建一个HelloServlet类进行测试。
public class HelloServlet extends HttpServlet {
//get和post只是实现请求的不同方式,可以互相调用,业务逻辑一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//响应流
writer.print("hello servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
在web.xml文件中注册该servlet
hello
com.leo.servlet.HelloServlet
hello
/hello
之后发布tomcat进行测试
结果:
环境已经部署完成,接下来开始学习。
2. 注册servlethello //给该servlet起个名字,自定义com.leo.servlet.HelloServlet //绑定该servlet类hello //对应上面servlet的名字/hello //设置浏览器访问的url地址
有servlet标签,就要对应有一个servlet-mapping标签。
class内绑定servlet类,注意该类必须是一个servlet类。
url-pattern栏中设置浏览器访问的url地址。如上图设置,最终访问的是 localhost:8080/hello
3.servlet类如何让自己写的类成为一个servlet?
public class HelloServlet extends HttpServlet
只需要让我们的类继承HttpServlet类即可。
该类中存在着许多方法,我使用时一般需要重写其中的doGet以及doPost方法,根据需求,这两者相互调用即可
4.servlet中context的使用 4.1 传递数据编写一个HelloServlet类
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter() 初始化参数
//this.getServletConfig() 初始化Servlet配置
//this.getServletContext() Servlet上下文
ServletContext context = this.getServletContext();
String name="林志玲";//数据
context.setAttribute("username",name);//将数据保存在了context中,名字为username,值为name
}
}
在servlet类中,通过this.getServletContext()可以获取Servlet的上下文context。
context.setAttribute方法则起到了数据储存的功能。
我们如何在别的servlet中获取该数据呢?编写另一个类GetServlet
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取context上下文
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setCharacterEncoding("utf-8");//设置编码集防止乱码
resp.setContentType("text/html");//告诉浏览器以文本形式展示
PrintWriter writer = resp.getWriter();
writer.print(username);//展示在浏览器界面
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
首先通过this.getServletContext()获取上下文context。这里不同servlet类所获得的的context都会是同一个context。
context.getAttribute方法则是取得之前所保存的数据。名称需要一致(username)。
在web.xml中注册这两个servlet
hello com.leo.servlet.HelloServlet hello /hello getc com.leo.servlet.GetServlet getc /getc
此时我们首先访问HelloServlet: localhost:8080/hello将数据(username:林志玲)存入
在访问GetServlet:localhost:8080/getc 将(username:林志玲)获取并展示在网页:
4.2 获取配置参数我们可以在web.xml中为servlet配置一些参数:
url
jdbc:mysql://localhost:3306/mybatis
同时也可以通过context将它们取得。
编写类:
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取context上下文
ServletContext context = this.getServletContext();
//获取配置中的信息
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
依然先获取context对象。
通过context.getInitParameter方法获取参数(url),打印在网页上。
注册servlet:
gp com.leo.servlet.ServletDemo03 gp /gp
访问: localhost:8080/gp
4.3 转发页面在我们访问一个页面的时候,通过转发功能,会跳转到另外一个指定的页面
编写类:
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取context上下文
ServletContext context = this.getServletContext();
System.out.println("进入Demo04");
//获取转发器
RequestDispatcher dispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
dispatcher.forward(req,resp);//调用foreword方法进行转发
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
context.getRequestDispatcher方法获取转发器,其参数就填你所要转发的路径,这里转发到上一个页面 localhost:8080/gp。
dispatcher通过forward(req,resp)方法进行页面转发。
注册servlet:
sd4 com.leo.servlet.ServletDemo04 sd4 /sd4
首先尝试访问 localhost:8080/sd4 :
发现url地址栏仍然是我们访问的 localhost:8080/sd4 ,然而页面却跳转到了 localhost:8080/gp 的内容,这就是转发功能。
4.4 获取配置文件以及其中的内容通过context也是能够读取配置文件中的内容的,下面进行测试。
在resources文件夹下创建一个配置文件db.properties:
username=root password=123456
写一个servlet类:
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");//当前web下的路径
Properties prop = new Properties();
prop.load(is);
resp.getWriter().print(prop.getProperty("username"));
resp.getWriter().print(prop.getProperty("password"));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
通过流的形式把配置文件读取。
getResourceAsStream()中的路径,不能直接填写"db.properties",必须填写其在web项目发布之后所存在的位置。寻找方法:
在target文件夹下-->找到所发布的web项目-->WEB-INF-->classes-->db.properties。
注册servlet:
sd5 com.leo.servlet.ServletDemo05 sd5 /sd5
访问:
4.5 总结
自定义的servlet类必须继承HttpServlet,这样才代表着此类是一个servlet。
重写HttpServlet的doGet和doPost方法,两者可以互相调用。
需要在web.xml中注册自定义servlet类。
若要使用ServletContext中的功能,通过this.getServletContext,取得context对象,即可使用。
5.response的使用 5.1 下载文件
将一个图片文件放到resources文件夹下
自定义servlet类:
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取下载文件的路径
String realPath = "F:\java\idea\javaweb\response\target\response\WEB-INF\classes\1.png";
System.out.println("下载文件的路径"+realPath);
//2.获取下载文件的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\") + 1);
//3.设置让浏览器支持下载我们的东西
resp.setHeader("Content-disposition","attachment;filename"+fileName);
//4.获取下载文件输入流
FileInputStream is = new FileInputStream(realPath);
//5.创建缓冲区
byte[] bytes = new byte[1024];
int len = 0;
//6.获取OutputStream对象
ServletOutputStream os = resp.getOutputStream();
//7.将OutputStream流写入buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
while ((len = is.read(bytes))>0){
os.write(bytes,0,len);
}
is.close();
os.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
注册servlet:
down com.leo.servlet.FileServlet down /down
访问 localhost:8080/down 后即可下载该图片文件。
5.2 自定义图片编写servlet类
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置浏览器3秒钟刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();//笔
//设置背景颜色
g.setColor(Color.white);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.blue);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器这是个图片,用图片的方式打开
resp.setContentType("image/jpeg");
//不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数
public String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
sb.append("0");
}
num=sb.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
注册servlet
ImageServlet com.leo.servlet.ImageServlet ImageServlet /im
访问:
5.3 重定向(重要)前2个功能在应用场景不大,重定向功能则是resp十分重要的应用。
编写servlet类:
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/im");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
resp的sendRedirect方法实现了重定向功能。方法的参数就填写你所要重定向到的页面。
注册servlet:
redirect com.leo.servlet.RedirectServlet redirect /red
访问 http://localhost:8080/red:
我们输入http://localhost:8080/red,访问到的地址却是im (80×20)。这就是重定向,地址栏会发生改变。
5.5 总结response中最重要的应用是重定向,记住sendRedirect方法即可。
6.request的使用 6.1 获取参数通过req.getParameter()方法,可以获取请求中携带的参数。
编写index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录
登录
这里我们通过表单的形式,能够上传我们所命名的属性:username、password、hobby
编写servlet:
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
System.out.println("---------");
System.out.println(username + " " + password);
System.out.println("---------");
System.out.println(Arrays.toString(hobbies));
//通过request转发
req.getRequestDispatcher("/successful.jsp").forward(req,resp);
}
}
这里可以看到的是,我们使用了req.getParameter()方法,来获取上传到表单的参数,获取名字必须一致。
注册servlet:
LoginServlet com.leo.servlet.LoginServlet LoginServlet /login
结果:
访问了登录页面后,展示的是index.jsp的界面。我们填好内容,并且提交后:
可以看到控制台确实获取到了我们的参数。
6.2 转发转发是request中最常使用的方法,其功能是将此页面转发到另一页面,也是实现页面的跳转。
代码和6.1中一样。我们通过req.getRequest.Dispatcher("").forward(req,resp)的方法,实现了页面的转发。其中,第一个括号内要填的参数是你所要转发到的页面。
为了测试转发,在编辑一个successful.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
successful!
结果:
当我们点击提交后,跳转到了successful.jsp页面,完成了页面的转发。
6.3 request转发和response重定向的区别相同点:都能实现页面的跳转
不同点:
转发:
可见的URL地址栏并未发生改变,仍然是跳转前界面的地址
重定向:
如上面,访问的是http://localhost:8080/red,然而跳转到此页面时,顶部的URL地址栏也发生了变化。
更多异同参考其他文档。



