6、Servlet

6.1、Servlet简介

  • Servlet就是sun公司开发动态web的一门技术
  • Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    • 编写一个类,实现Servlet接口
    • 把开发好的Java类部署到web服务器中。

把实现了Servlet接口的Java程序叫做,Servlet

6.2、HelloServlet

Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet

\1. 构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立

Moudel;这个空的工程就是Maven主工程;

\2. 关于Maven父子工程的理解:

​ 父项目中会有

<modules><module>servlet-01</module>
</modules>

​ 子项目会有

<parent><artifactId>javaweb-02-servlet</artifactId><groupId>com.kuang</groupId><version>1.0-SNAPSHOT</version>
</parent>

父项目中的java子项目可以直接使用

son extends father

\3. Maven环境优化

​ \1. 修改web.xml为最新的

​ \2. 将maven的结构搭建完整

\4. 编写一个Servlet程序

\1. 编写一个普通类

\2. 实现Servlet接口,这里我们直接继承HttpServlet

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,Serlvet");
}
@Override
protected void doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);
}
}

\5. 编写Servlet的映射

为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,

所以我们需要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径;

<!--注册Servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

\6. 配置Tomcat

​ 注意:配置项目发布的路径就可以了

\7. 启动测试,OK!

6.3、Servlet原理

Servlet是由Web服务器调用,web服务器在收到浏览器请求之后,会:

6.4、Mapping问题

\1. 一个Servlet可以指定一个映射路径

<servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern>
</servlet-mapping>

\2. 一个Servlet可以指定多个映射路径

<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello5</url-pattern>
</servlet-mapping>

\3. 一个Servlet可以指定通用映射路径

<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>

\4. 默认请求路径

<!--默认请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

\5. 指定一些后缀或者前缀等等….

<!--可以自定义后缀实现请求映射注意点,*前面不能加项目映射的路径hello/sajdlkajda.qinjiang-->
<servlet-mapping><servlet-name>hello</servlet-name><url-pattern>*.qinjiang</url-pattern>
</servlet-mapping>

\6. 优先级问题

​ 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

6.5、ServletContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

1、共享数据

我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;

public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext context = this.getServletContext();//this.getInitParameter() 初始化参数// this.getServletConfig() Servlet配置// this.getServletContext() Servlet上下文String username = "epfox";context.setAttribute("username", username);}
}
public class GetServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext context = this.getServletContext();String username = (String) context.getAttribute("username");resp.setContentType("text/html");resp.setCharacterEncoding("utf-8");resp.getWriter().print("名字"+username);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
  <servlet><servlet-name>hello</servlet-name><servlet-class>com.epfox.servlet.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping><servlet><servlet-name>getc</servlet-name><servlet-class>com.epfox.servlet.GetServlet</servlet-class></servlet><servlet-mapping><servlet-name>getc</servlet-name><url-pattern>/getc</url-pattern></servlet-mapping>

测试访问结果;

2、获取初始化参数

  <!--配置一些web应用初始化参数--><context-param><param-name>url</param-name><param-value>jdbc:mysql://localhost:3306/mybatis</param-value></context-param>
public class ServletDemo03 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext context = this.getServletContext();String url = context.getInitParameter("url");resp.getWriter().print(url);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

3、请求转发

    @Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext context = this.getServletContext();System.out.println("进入了ServletDemo04");
//        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
//        requestDispatcher.forward(req,resp); //调用forword实现请求转发context.getRequestDispatcher("/gp").forward(req,resp);}

4、读取资源文件

Properties

  • 在java目录下新建properties
  • 在resources目录下新建properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath:

思路:需要一个文件流;

username=root
password=123456
public class ServletDemo05 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/epfox/servlet/aa.properties");InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");Properties prop = new Properties();prop.load(is);String user = prop.getProperty("username");String pwd = prop.getProperty("password");resp.getWriter().print(user+":"+pwd);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

访问测试即可ok;

6.6、HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

1、简单分类

负责向浏览器发送数据的方法

ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;

负责向浏览器发送响应头的方法

void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);

响应的状态码

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

2、下载文件

\1. 向浏览器输出消息 (一直在讲,就不说了)

\2. 下载文件

​ \1. 要获取下载文件的路径

​ \2. 下载的文件名是啥?

​ \3. 设置想办法让浏览器能够支持下载我们需要的东西

​ \4. 获取下载文件的输入流

​ \5. 创建缓冲区

​ \6. 获取OutputStream对象

​ \7. 将FileOutputStream流写入到buffer缓冲区

​ \8. 使用OutputStream将缓冲区中的数据输出到客户端!

public class FileServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String realPath = "/Users/maby/IdeaProjects/javaweb-03-servlet/response/src/main/resources/微信.png";System.out.println("下载文件的路径:" + realPath);String fileName = realPath.substring(realPath.lastIndexOf("/") + 1);resp.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));FileInputStream in = new FileInputStream(realPath);int len = 0;byte[] buffer = new byte[1024];ServletOutputStream out = resp.getOutputStream();while((len=in.read(buffer))>0){out.write(buffer,0, len);}in.close();out.close();}

3、验证码功能

验证怎么来的?

  • 前端实现
  • 后端实现,需要用到 Java 的图片类,生产一个图片
public class ImageServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {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());}private 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;}

4、实现重定向

B一个web资源收到客户端A请求后,B他会通知A客户端去访问另外一个web资源C,这个过程叫重定向

常见场景:

  • 用户登录
1 void sendRedirect(Stringvar1) throws IOException;

测试:

public class RedirectServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {/*resp.setHeader("Location","/r/img");resp.setStatus(302);*/resp.sendRedirect("/r/img");//重定向}

面试题:请你聊聊重定向和转发的区别?

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候,url不会产生变化
  • 重定向时候,url地址栏会发生变化;

5、简单实现登录重定向

<%--这里提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%><form action="${pageContext.request.contextPath}/login" method="get">用户名:<input type="text" name="username"> <br>密码:<input type="password" name="password"> <br><input type="submit">
</form>
public class RequestTest extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username+":"+password);resp.sendRedirect("/r/success.jsp");}
  <servlet><servlet-name>requset</servlet-name><servlet-class>com.epfox.servlet.RequestTest</servlet-class></servlet><servlet-mapping><servlet-name>requset</servlet-name><url-pattern>/login</url-pattern></servlet-mapping>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><h1>Success</h1></body>
</html>

6.7、HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;

获取参数,请求转发

public class LoginServlet extends HttpServlet {@Overrideprotected void doGet(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[] hobbys = req.getParameterValues("hobbys");System.out.println("==================");System.out.println(username);System.out.println(password);System.out.println(Arrays.toString(hobbys));System.out.println("====================");System.out.println(req.getContextPath());req.getRequestDispatcher("/success.jsp").forward(req,resp);}

面试题:请你聊聊重定向和转发的区别?

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候,url不会产生变化 307
  • 重定向时候,url地址栏会发生变化; 302

JavaWeb-6Servlet相关推荐

  1. java学习之javaWeb

    Web开发 1.CS和BS的异同点 2.Tomcat 2.1新建项目-部署-运行-访问(底层原理) 2.2在IDEA下新建javaWeb项目 3.Servlet 3.1Servlet获取参数 3.2S ...

  2. javaWeb——Servlet

    Servlet 系统架构 B/S结构的系统通信原理(没有涉及到Java小程序) 关于WEB服务器软件 实现一个最基本的web应用(这个web应用中没有java小程序) 对于一个动态的web应用来说,一 ...

  3. JavaWeb笔记01

    文章目录 JavaWeb(狂神说Java) 1.基本概念 1.1前言 1.2web应用程序 1.3静态web 1.4 动态web 2.web服务器 2.1技术讲解 2.2web服务器 3.Tomcat ...

  4. 使用maven搭建ssm框架的javaweb项目

    目前主流的javaweb项目,常会用到ssm(Spring+Spring MVC+Mybatis)框架来搭建项目的主体框架,本篇介绍搭建SSM框架的maven项目的实施流程.记之共享! 一.SSM框架 ...

  5. javaweb学习总结(二十三)——jsp自定义标签开发入门

    一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...

  6. javaWeb -- HTTP协议

    笔记摘要: 作为web开发的前奏,这里介绍了什么是HTTP协议,HTTP请求与HTTP响应信息的介绍 一.什么是HTTP协议 客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一 ...

  7. Java项目:个人博客系统(java+SSM+Mysql+Servlet+JavaWeb)

    源码获取:博客首页 "资源" 里下载! 一.项目简述 项目内容包括:首页,登陆,新建文章,搜索,登陆日志,登录次数,评论统计,相关信息,文章列表等其他相关功能 另外:系统采用MVC ...

  8. 在linux下部署安装Tomact并运行javaWeb工程

    1.下载并安装xftp5 2.上传Tomact服务器 3.安装Tomact服务器 3.1解压Tomact服务器压缩包 解压到当前目录下 3.2配置环境变量 tomcat服务器运行时是需要JDK支持的, ...

  9. 超详细的Java面试题总结(四 )之JavaWeb基础知识总结

    系列文章请查看: 超详细的Java面试题总结(一)之Java基础知识篇 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java ...

  10. JavaWeb学习笔记——DOM4J

    下载的地址为:http://www.dom4j.org/dom4j-1.6.1/ import java.io.File; import java.io.FileOutputStream; impor ...

最新文章

  1. java注释跳转方法,Java自定义注解实现Router跳转
  2. 有些人一眼就能认出来,你认出来几个?
  3. cscope使用技巧
  4. Discuz验证码识别(上线篇)-写给程序员的TensorFlow教程
  5. 基于matlab的语音信号,科学网—[转载]【信息技术】【2014.06】【含源码】基于MATLAB的语音信号处理与分析 - 刘春静的博文...
  6. 机器学习里面常用知识
  7. win10照片查看器_图片打开方式中找不到Windows图片查看器怎么办
  8. Android开发笔记(一百六十九)利用BottomNavigationView实现底部标签栏
  9. python学习之面向对象学习进阶
  10. Ubuntu使用U盘把从互联网上下载的安装包及其依赖更新到内部机
  11. 随笔记----关于python 和C++ 里面的与或问题
  12. Gephi实战教程:从零开始
  13. 用计算机如何算针入度指数,沥青针入度指数怎么计算?需要计算公式,最好说的详细一点!...
  14. java学习笔记(二):Spring-security的Remember-me配置,以及配置Session管理器防止Session fixation
  15. 快递查询方法一键查询物流信息
  16. Codeforces Round #649 D. Ehab‘s Last Corollary 【思维,二分图,环】
  17. 阿里巴巴按关键字搜索新品数据 API
  18. HDU 5976 Detachment 逆元
  19. Android studio使用中问题集锦
  20. 电路的网孔电流法建模 matlab,第3节 网孔电流法

热门文章

  1. Windows运行机理——消息与消息队列
  2. DirectX11 交换链是什么
  3. java util什么意思_java.util中,util是什么意思
  4. 本地服务器上传文件,本地服务器上传文件
  5. python中调用julia_Julia引入PyCall报错解决方法
  6. 利用python选股的思路
  7. stm32 火灾自动报警及联动控制源码_火灾自动报警与消防联动控制系统
  8. 前端性能优化的七种方法
  9. CSS教程:dashed和dotted的区别
  10. 如何加密文件及文件夹