JavaWeb-6Servlet
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相关推荐
- java学习之javaWeb
Web开发 1.CS和BS的异同点 2.Tomcat 2.1新建项目-部署-运行-访问(底层原理) 2.2在IDEA下新建javaWeb项目 3.Servlet 3.1Servlet获取参数 3.2S ...
- javaWeb——Servlet
Servlet 系统架构 B/S结构的系统通信原理(没有涉及到Java小程序) 关于WEB服务器软件 实现一个最基本的web应用(这个web应用中没有java小程序) 对于一个动态的web应用来说,一 ...
- JavaWeb笔记01
文章目录 JavaWeb(狂神说Java) 1.基本概念 1.1前言 1.2web应用程序 1.3静态web 1.4 动态web 2.web服务器 2.1技术讲解 2.2web服务器 3.Tomcat ...
- 使用maven搭建ssm框架的javaweb项目
目前主流的javaweb项目,常会用到ssm(Spring+Spring MVC+Mybatis)框架来搭建项目的主体框架,本篇介绍搭建SSM框架的maven项目的实施流程.记之共享! 一.SSM框架 ...
- javaweb学习总结(二十三)——jsp自定义标签开发入门
一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...
- javaWeb -- HTTP协议
笔记摘要: 作为web开发的前奏,这里介绍了什么是HTTP协议,HTTP请求与HTTP响应信息的介绍 一.什么是HTTP协议 客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一 ...
- Java项目:个人博客系统(java+SSM+Mysql+Servlet+JavaWeb)
源码获取:博客首页 "资源" 里下载! 一.项目简述 项目内容包括:首页,登陆,新建文章,搜索,登陆日志,登录次数,评论统计,相关信息,文章列表等其他相关功能 另外:系统采用MVC ...
- 在linux下部署安装Tomact并运行javaWeb工程
1.下载并安装xftp5 2.上传Tomact服务器 3.安装Tomact服务器 3.1解压Tomact服务器压缩包 解压到当前目录下 3.2配置环境变量 tomcat服务器运行时是需要JDK支持的, ...
- 超详细的Java面试题总结(四 )之JavaWeb基础知识总结
系列文章请查看: 超详细的Java面试题总结(一)之Java基础知识篇 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java ...
- JavaWeb学习笔记——DOM4J
下载的地址为:http://www.dom4j.org/dom4j-1.6.1/ import java.io.File; import java.io.FileOutputStream; impor ...
最新文章
- java注释跳转方法,Java自定义注解实现Router跳转
- 有些人一眼就能认出来,你认出来几个?
- cscope使用技巧
- Discuz验证码识别(上线篇)-写给程序员的TensorFlow教程
- 基于matlab的语音信号,科学网—[转载]【信息技术】【2014.06】【含源码】基于MATLAB的语音信号处理与分析 - 刘春静的博文...
- 机器学习里面常用知识
- win10照片查看器_图片打开方式中找不到Windows图片查看器怎么办
- Android开发笔记(一百六十九)利用BottomNavigationView实现底部标签栏
- python学习之面向对象学习进阶
- Ubuntu使用U盘把从互联网上下载的安装包及其依赖更新到内部机
- 随笔记----关于python 和C++ 里面的与或问题
- Gephi实战教程:从零开始
- 用计算机如何算针入度指数,沥青针入度指数怎么计算?需要计算公式,最好说的详细一点!...
- java学习笔记(二):Spring-security的Remember-me配置,以及配置Session管理器防止Session fixation
- 快递查询方法一键查询物流信息
- Codeforces Round #649 D. Ehab‘s Last Corollary 【思维,二分图,环】
- 阿里巴巴按关键字搜索新品数据 API
- HDU 5976 Detachment 逆元
- Android studio使用中问题集锦
- 电路的网孔电流法建模 matlab,第3节 网孔电流法