xml设置
创建项目需要勾选下图的创建xml(适用于3.0以下版本,3.0以上的可以跳过使用下面的注解开发)
创建完项目后,找到web---WEB-INF---web.xml配置以下代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 配置servlet路径 -->
<servlet>
<!-- 起名 -->
<servlet-name>demo1</servlet-name>
<!-- 配置全类名(全限定名) -->
<servlet-class>com.jwz.web.servlet.ServletDemo01</servlet-class>
<!--
指定servlet的创建时机
1.第一次被访问时创建
<load-on-startup>的值为负数
2.在服务器启动时创建
<load-on-statup>的值为日或正整数
启动服务器,注意初始化方法打印的值
-->
<load-on-startup>0</load-on-startup>
</servlet>
<!-- 配置servlet的mapping -->
<servlet-mapping>
<!--下面名字和上面保持一致-->
<servlet-name>demo1</servlet-name>
<!--路径-->
<url-pattern>/xiaoji</url-pattern>
</servlet-mapping>
</web-app>
注解开发
@WebServlet() //配置访问的路径,无需配置xml,类似xml的url-pattern
@WebServlet(value = "/lujing")
@WebServlet(urlPatterns = "/lujing") //以上两种方式均可以配置访问路径
//一般默认使用value,因为value可以省略,所以可以简写下面形式
@WebServlet("/lujing")
servlet结构说明
@webservlet("/xiaoji")
public class ServletDemo01 implements Servlet {
/**
* 初始化方法
* 在servlet被创建时,只会执行一次
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init.........");
}
/**
* 获取ServletConfig对象
* ServletConfig:servlet的配置对象
* @return
*/
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
*提供服务方法
* 每一次servlet被访问时执行,执行多次
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello servlet");
}
/**
* 获取servlet的一些信息
* @return
*/
@Override
public String getServletInfo() {
return null;
}
/**
*销毁方法
*服务器正常关闭时执行,执行一次
*/
@Override
public void destroy() {
System.out.println("destroy....");
}
}
路径的设置
package com.jwz.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//定义多个路径,以下三个路径均可以访问
/**
* 路径定义规则
* /XXX
* /XXX/XXX:多层路径,目录结构
* *.xiaoji
*/
//@WebServlet({"/d4","/dd4","/ddd4"})
//@WebServlet("/user/demo04")//多层路径
//@WebServlet("/user/*")//多层路径最后一层为任意匹配路径
//@WebServlet("/*")//为任意匹配路径
@WebServlet("*.xiaoji")//任意字段.xiaoji才能访问
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo04....");
}
}
继承关系
直接继承GenericServlet,相当于只需要重写servlet的service方法
public class ServletDemo02 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet02");
}
}
继承HttpServlet有两个方法分别监听get和post的请求
@WebServlet("/xiaoji1")
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doget");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("dopost");
}
}
HttpServlet中的request方法
在继承的HttpServlet中的request获取请求行数据的方法
- 获取请求方式 :GET * String getMethod() 2. 获取虚拟目录:/day14 * String getContextPath() 3. 获取Servlet路径: /demo1 * String getServletPath() 4. 获取get方式请求参数:name=zhangsan * String getQueryString() 5. 获取请求URI:/day14/demo1 * String getRequestURI(): /day14/demo1 * StringBuffer getRequestURL() :http://localhost/day14/demo1 * URL:统一资源定位符 : http://localhost/day14/demo1 * URI:统一资源标识符 : /day14/demo1 6. 获取协议及版本:HTTP/1.1 * String getProtocol() 7. 获取客户机的IP地址: * String getRemoteAddr()
@WebServlet("/demo01")
public class demo01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//发送请求为Get,这里使用doget
//获取请求方式:GET
System.out.println(request.getMethod());
//获取虚拟目录:/servlet_war_exploded
System.out.println(request.getContextPath());
//获取servlet路径:/demo01
System.out.println(request.getServletPath());
//获取get请求参数:name=zhangsan&age=28
System.out.println(request.getQueryString());
//获取请求的URI:/servlet_war_exploded/demo01
System.out.println(request.getRequestURI());
//获取请求的URL:http://localhost:8080/servlet_war_exploded/demo01
System.out.println(request.getRequestURL());
//获取协议及版本:HTTP/1.1
System.out.println(request.getProtocol());
//获取客户机的ip地址:0:0:0:0:0:0:0:1
System.out.println(request.getRemoteAddr());
}
}
在继承的HttpServlet中的request获取请求头数据的方法
- String getHeader(String name):通过请求头的名称获取请求头的值 * Enumeration getHeaderNames():获取所有的请求头名称
package com.jwz.servlet.request方法演示;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/**
* 演示request获取请求行数据(具体方法看txt文本)
*/
@WebServlet("/demo02")
public class demo02获取请求头 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//演示获取请求头数据
//获取所有请求头名称
Enumeration<String> e = request.getHeaderNames();
//遍历
while(e.hasMoreElements()){
String name = e.nextElement();
//根据名称获取请求头的值
String value = request.getHeader(name);
System.out.println(name+"-----"+value);
}
System.out.println("=====================");
//获取指定请求头(user-agent)数据
String agent = request.getHeader("user-agent");
//判断浏览器的版本
if(agent.contains("Chrome")){
System.out.println("获取到谷歌浏览器");
}else if(agent.contains("Firefox")){
System.out.println("获取到火狐浏览器");
}
System.out.println("=====================");
//获取指定请求头(referer)数据
//直接用浏览器访问打印为null
//在web文件夹创建htmla标签为<a href="/虚拟目录/访问路径">referer演示</a>
//然后访问html文件:http://localhost:8080/虚拟目录/referer.html,通过超链接点击访问地址即可
//最后打印出:http://localhost:8080/servlet_war_exploded/referer.html
//也就是html文件访问路径
String referer = request.getHeader("referer");
System.out.println(referer);
}
}
referer的html文件内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/servlet_war_exploded/demo02">referer演示</a>
</body>
</html>
上面所有代码统一打印出来的结果
在继承的HttpServlet中的request获取请求体数据的方法
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数 * 步骤: 1. 获取流对象 * BufferedReader getReader():获取字符输入流,只能操作字符数据 * ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据 * 在文件上传知识点后讲解 2. 再从流对象中拿数据
示例java代码(post请求)
@WebServlet("/demo03")
public class demo03获取请求体 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求消息体
//1.获取字符流
BufferedReader br = req.getReader();
//2.读取数据
String line=null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
//最后开启服务器,访问body.html,点提交后看控制台
}
}
示例上面代码里的body.html代码(post请求)
<body>
<--action里面为虚拟目录加访问映射名-->
<form action="/xiaoji/demo03" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit" value="提交"><br>
</form>>
</body>
访问body.html以后,表单填写账号密码,点击提交以后的效果图
其他功能:
1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
1. String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
2. String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
3. Enumeration<String> getParameterNames():获取所有请求的参数名称
4. Map<String,String[]> getParameterMap():获取所有参数的map集合
当两个请求业务逻辑相同时,可以使用this.doPost(request,response)
直接调用另一个请求的方法。
5.中文乱码问题:
* get方式:tomcat 8 已经将get方式乱码问题解决了
* post方式:会乱码
* 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
""
请求转发:一种在服务器内部的资源跳转方式
1. 步骤:
1-1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path),
1-2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
如:
另一个资源的访问路径为xiaoji
RequestDispatcher xiaoji=request.getRequestDispatcher("/xiaoji")
xiaoji.forward(request,response)
通过以上两行代码就能完成转发操作(可以用链式编程,比较建议)
2. 特点:
2-1. 浏览器地址栏路径不发生变化
2-2. 只能转发到当前服务器内部资源中。
2-3. 转发是一次请求
3. 共享数据:
3-1. 域对象:一个有作用范围的对象,可以在范围内共享数据
3-2. request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
3-3. 方法:
3-3-1. void setAttribute(String name,Object obj):存储数据
3-3-2. Object getAttitude(String name):通过键获取值
3-3-3. void removeAttribute(String name):通过键移除键值对
4. 获取ServletContext:
4-1. ServletContext getServletContext()
response
- 功能:设置响应消息 1. 设置响应行 1. 格式:HTTP/1.1 200 ok 2. 设置状态码:setStatus(int sc) 2. 设置响应头:setHeader(String name, String value) 3. 设置响应体: * 使用步骤: 1. 获取输出流 * 字符输出流:PrintWriter getWriter() * 字节输出流:ServletOutputStream getOutputStream() 2. 使用输出流,将数据输出到客户端浏览器
字符输出流的使用
@WebServlet("/res03")
public class demo03 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//乱码问题解决:
//第一种写法(有不足,只能跟着浏览器编码设置,并不能让浏览器跟代码的编码走)
//获取流对象之前,设置流的默认编码:IS0-8859-1设置为:GBK
//response.setCharacterEncoding("utf-8");
//第二种写法(建议)
//告诉浏览器,服务器发送的消息.体数据的编码。建议浏览器使用该编码解码
//response.setHeader("content-type","text/html;charset=utf-8");
//第三种写法(非常建议!!!),最简单又实用
response.setContentType("text/html;charset=utf-8");
//1.获取字符输出流
PrintWriter pw = response.getWriter();
//2.输出数据
pw.write("<h1>哈喽,response</h1>");
}
}
字节输出流使用
@WebServlet("/res04")
public class demo04获取字节输出流 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//防止乱码
response.setContentType("text/html;charset=utf-8");
//1.获取字节输出流
ServletOutputStream sos = response.getOutputStream();
//2.输出数据,并将数据转为字节类型
sos.write("你好:hello".getBytes());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
重定向代码点击参考本人这篇博客代码即可
* 重定向的特点:redirect
1. 地址栏发生变化
2. 重定向可以访问其他站点(服务器)的资源
3. 重定向是两次请求。不能使用request对象来共享数据
* 转发的特点:forward
1. 转发地址栏路径不变
2. 转发只能访问当前服务器下的资源
3. 转发是一次请求,可以使用request对象来共享数据
* forward 和 redirect 区别
* 路径写法:
1. 路径分类
1. 相对路径:通过相对路径不可以确定唯一资源
* 如:./index.html
* 不以/开头,以.开头路径
* 规则:找到当前资源和目标资源之间的相对位置关系
* ./:当前目录
* ../:后退一级目录
2. 绝对路径:通过绝对路径可以确定唯一资源
* 如:http://localhost/day15/responseDemo2 /day15/responseDemo2
* 以/开头的路径
* 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
* 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
* 建议虚拟目录动态获取:request.getContextPath()
* <a> , <form> 重定向...
* 给服务器使用:不需要加虚拟目录
* 转发路径
简单验证码实现(用线条充当干扰)
成品图
刷新出现随机数和随机线条
代码实现
@WebServlet("/yzm")
public class 验证码实现 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一张图片,在内存中存图片(验证码图片对象)
int width=100;
int height=50;
//宽高和图片类型,使用BufferedImage里面的rgb也就是表示三原色红绿蓝格式的图片(也可以选其他的)
BufferedImage img=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//美化图片
//1.填充背景色
Graphics g = img.getGraphics();//画笔对象
g.setColor(Color.pink);//设置画笔颜色
g.fillRect(0,0,width,height);
//2.画边框
g.setColor(Color.blue);
g.drawRect(0,0,width-1,height-1);
//3.写验证码
String str="ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random r=new Random();
for (int i = 1; i <= 4; i++) {
int index = r.nextInt(str.length());//随机索引
char ch = str.charAt(index);//随机字符
g.drawString(ch+"",width/5*i,height/2);
}
//4.画干扰线
g.setColor(Color.GREEN);//颜色
//g.drawLine(1,1,30,30);//起末点坐标点
//十条线循环十次
for (int i = 0; i < 10; i++) {
//随机生成坐标点
int x1 = r.nextInt(width);
int x2 = r.nextInt(width);
int y1 = r.nextInt(height);
int y2 = r.nextInt(height);
g.drawLine(x1,y1,x2,y2);//起末点坐标点
}
//将图片输出到页面展示
//ImageIO.write可以将内存中的图片写入到页面上
ImageIO.write(img,"jpg",resp.getOutputStream());
}
}
ServletContext对象:
1. 概念:代表整个web应用,可以和程序的容器(服务器)来通信
2. 获取:
1. 通过request对象获取
request.getServletContext();
2. 通过HttpServlet获取
this.getServletContext();
以下为代码实现:
@WebServlet("/con01")
public class demo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletContext对象获取
//1. 通过request对象获取
// request.getServletContext();
ServletContext co1 = req.getServletContext();
//2. 通过HttpServlet获取
// this.getServletContext();
ServletContext co2 = this.getServletContext();
System.out.println(co1);
System.out.println(co2);
System.out.println(co1==co2);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
3. 功能:
1. 获取MIME类型:
* MIME类型:在互联网通信过程中定义的一种文件数据类型
* 格式: 大类型/小类型 text/html image/jpeg
* 获取:String getMimeType(String file)
以下是代码实现:
@WebServlet("/con02")
public class demo02获取MIME类型 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.通过httpServlet获取对象
ServletContext servletContext = this.getServletContext();
//2.定义文件名称'
String filename="a.jpg";
//获取MIME类型
String mimeType = servletContext.getMimeType(filename);
System.out.println(mimeType);//image/jpeg
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
2. 域对象:共享数据
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)
以下是代码实现:
页面一代码:
@WebServlet("/con03")
public class demo03获取域对象一 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.通过httpServlet获取对象
ServletContext servletContext = this.getServletContext();
//2.设置数据
servletContext.setAttribute("msg","haha");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
------------------------------------------------------------------------------
页面二代码:
@WebServlet("/con04")
public class demo03获取域对象二 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.通过httpServlet获取对象
ServletContext servletContext = this.getServletContext();
//2.获取数据
Object msg = servletContext.getAttribute("msg");
System.out.println(msg);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
通过访问页面二可以共享页面一存储的数据(同样所有用户都可以访问这个数据)
* ServletContext对象范围:所有用户所有请求的数据
3. 获取文件的真实(服务器)路径
1. 方法:String getRealPath(String path)
//1.通过httpServlet获取对象
ServletContext servletContext = this.getServletContext();
String b = servletContext .getRealPath("/b.txt");//web目录下资源访问
System.out.println(b);
String c = servletContext .getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(c);
String a = servletContext .getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
System.out.println(a);