概念:Extensible Markup Language 可扩展标记语言
功能:
XML与HTML的区别
基本语法:
快速入门
<users>
<user id = '1'>
<name>zhangsanname>
<age>23age>
<gender>malegender>
<br/>
user>
<user id = '2'>
<name>lisiname>
<age>24age>
<gender>femalegender>
user>
users>
文档声明
ISO-8859-1
指令(了解):结合css的
标签:标签名称自定义的
属性:
id属性值唯一
文本:
约束:规定xml文档的书写规则
DTD:
DOCTYPE students SYSTEM "student.dtd">
<students>
<student number="s001">
<name>zhangsanname>
<age>20age>
<sex>nansex>
student>
students>
引入:
.xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
.xsi:schemalocation="http://www.itcast.cn/xml student.xsd"
xmlns="http://www.itcast.cn/xml"
<xsd:schema xmlns="http://www.itcast.cn/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn/xml" elementFormDefault="qualified">
<xsd:element name="students" type="studentsType"/>
<xsd:complexType name="studentsType">
<xsd:sequence>
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
xsd:sequence>
xsd:complexType>
<xsd:complexType name="studentType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
xsd:sequence>
<xsd:attribute name="number" type="numberType" use="required"/>
xsd:complexType>
<xsd:simpleType name="sexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
xsd:restriction>
xsd:simpleType>
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="256"/>
xsd:restriction>
xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="heima_\d{4}"/>
xsd:restriction>
xsd:simpleType>
xsd:schema>
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/xml"
xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
>
<student number="heima_0001">
<name>tomname>
<age>18age>
<sex>malesex>
student>
students>
解析:操作xml文档,将文档中的数据读取到内存中
操作xml文档
解析xml的方式:
xml常见的解析器:
Jsoup:jsoup 是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,css
以及类似于jQuery的操作方式来取出和操作数据
快速入门:
package com.xh.Jsoup;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.IOException;
public class JsoupDome {
public static void main(String[] args) throws IOException {
//获取xml文件地址
String path = JsoupDome.class.getClassLoader().getResource("student.xml").getPath();
//使用解析器获取Document对象
Document parse = Jsoup.parse(new File(path),"utf-8");
//获取元素对象
Elements name = parse.getElementsByTag("name");
System.out.println(name.size());
}
}
Jsoup:工具类,可以解析html或xml文档,返回Document对象
Document:文档对象。代表内存中的dom树
Elements:元素Element对象的集合。可以当做ArrayList
Element:元素对象
Node:节点对象
selector:选择器
XPath:XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某位置的语言
package com.xh.Jsoup;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.seimicrawler.xpath.JXDocument;
import org.seimicrawler.xpath.JXNode;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class XpathDome {
public static void main(String[] args) throws IOException {
Document parse = Jsoup.parse(new File("D:\\开发资源\\project\\JavaWeb\\JDBC_Druid\\src\\main\\resources\\student.xml"),"utf-8");
JXDocument jxDocument = new JXDocument(parse.getAllElements());
List<JXNode> jxNodes = jxDocument.selN("//student");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
}
}
软件架构:
Client/Server
客户端/服务端Browser/Server
浏览器/服务器端资源分类:
网络通信三要素
服务器:安装了服务器软件的计算机
服务器软件:接收用户的请求,处理请求,做出响应
常见的java相关的web服务器软件:
JavaEE:Java语言在企业级开发中使用的技术规范的总和,一共规定了13项大的规范
Tomcat:web服务器软件
下载:http://tomcat.apache.org/
安装:解压缩压缩包即可
卸载:删除目录就行了
启动:
bin/startup.bat
,双击运行该文件即可
访问:浏览器输入:http://localhost:8080 回车访问自己
http://别人的ip:8080 访问别人
可能遇到的问题:
黑窗口一闪而过:
启动报错:
暴力:找到占用的端口号,并且肇东对应的进程,杀死该进程
netstat -ano
温柔:修改自身的端口号
conf/server.xml
<Connector port="8888" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8445" />
关闭:
bin/shutdown.bat
ctrl + c
配置:
部署项目的方式:
直接将项目放到webapps目录下即可。
/hello
:项目的访问路径–>虚拟目录配置conf/server.xml
文件
在
标签体中配置
<Context docBase="D:\hello" path="/hehe" />
docBase
:项目存放的路径path
:虚拟目录在conf\Catalina\localhost
创建任意名称的xml文件。在文件中编写
<Context docBase="D:\hello" />
静态项目和动态项目:
目录结构
java动态项目的目录结构:
– 项目的根目录
– WEB-INF目录:
– web.xml:web项目的核心配置文件
– classes目录:放置字节码文件的目录
– lib目录:放置依赖的jar包
将Tomcat集成到IDEA中,并且创建JavaEE的项目,部署项目
servlet:server applet
创建JavaEE项目
定义一个类,实现Servlet接口
package com.example.Servlet;
import javax.servlet.*;
import java.io.IOException;
public class ServletDome1 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 Tomcat....");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
<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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>domeservlet-name>
<servlet-class>com.example.Servlet.ServletDome1servlet-class>
servlet>
<servlet-mapping>
<servlet-name>domeservlet-name>
<url-pattern>/domeurl-pattern>
servlet-mapping>
web-app>
执行原理:
标签体内容
全类名Servlet中的生命周期方法:
标签下配置
的值为负数
的值为0或正整数Servlet3.0:
package javax.servlet.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";//相当于dome 配置
String[] value() default {};//代表urlPatterns()属性配置
String[] urlPatterns() default {};//相当于
int loadOnStartup() default -1;//相当于
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
IDEA会为每一个tomcat部署的项目单独建立一份配置文件
C:\Users\Dell\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\796a9df0-414d-4263-902d-b9cfe26122ab"
工作空间项目 和 tomcat部署的web项目
断电调试:使用“小虫子”启动dubug启动
Servlet – 接口
|
GenericServlet – 抽象类
|
HttpServlet – 抽象类
概念:Hyper Text Transfer Protocol 超文本传输协议
请求方式 请求url 请求协议/版本
GET /login.html HTTP/1.1
请求头:客户端浏览器告诉服务器一些信息
请求头名称:请求头值
请求空行
空行,就是用于分割POST请求的请求头,和请求体的
请求体(正文):
POST /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
username=zhangsan
响应消息:服务器端发送给客户端的数据
组成:协议/版本 响应状态码 状态码描述
响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
状态码都是3位数字
分类:
格式:头名称:值
常见的响应头:
Content-Type
:服务器告诉客户端本次响应体数据格式以及编码格式Content-disposition
:服务器告诉客户端以什么格式打开响应体数据
in-line
:默认值,在当前页面内打开attachment;filename=xxx
:以附件形式打开响应体。文件下载响应空行:空行
响应体:响应数据
HTTP/1.1 200 ОK
Content-Type: text/html;charset=UTF-8
Content-Length: 101
Date: Wed, 06 Jun 2018 07:08:42 GMTI
$Title$
hello, response
request对象和response对象的原理
request对象继承体系结构:
ServletRequest – 接口
| 继承
HttpServletRequest – 接口
| 实现
org.apache.catalina.connector.RequestFacade
类(tomcat编写)
获取请求行数据
GET /day14/demo1?name=zhangsan HTTP/1.1
方法:
获取请求方式:GET
String getMethod()
(*)获取虚拟目录:/day14
String getContextPath()
获取Servlet路径:/demo1
String getServletPath()
获取get方式请求参数:name = zhangsan
String getQueryString()
(*)获取请求URI:/day14/demo1
String getRequestURI():
/day14/demo1StringBuffer getRequestURL() :
http://localhost/day14/demo1获取协议及版本:HTTP/1.1
String getProtocol()
获取客户机的IP地址
String getRemoteAddr()
package com.example.Request;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "RequestDome1", value = "/RequestDome1")
public class RequestDome1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取请求方式:String getMethod()
String method = request.getMethod();
System.out.println("请求方式:"+method);
System.out.println("---------------");
//2.获取虚拟目录:String getContextPath()
String contextPath = request.getContextPath();
System.out.println("虚拟目录:"+contextPath);
System.out.println("---------------");
//3.获取Servlet路径:String getServletPath()
String servletPath = request.getServletPath();
System.out.println("Servlet路径"+servletPath);
System.out.println("---------------");
//4.获取get方式请求参数
String queryString = request.getQueryString();
System.out.println("get方式请求参数:"+queryString);
System.out.println("---------------");
//5.获取请求URI:String getRequestURI()
// StringBuffer getRequestURL()
String requestURI = request.getRequestURI();
String requestURL = request.getRequestURL().toString();
System.out.println("请求URI"+requestURI);
System.out.println("请求URI"+requestURL);
System.out.println("---------------");
//6.获取协议及版本:String getProtocol()
String protocol = request.getProtocol();
System.out.println("协议及版本"+protocol);
System.out.println("---------------");
//7.获取客户机的IP地址:String getRemoteAddr()
String remoteAddr = request.getRemoteAddr();
System.out.println("客户机的IP地址"+remoteAddr);
System.out.println("---------------");
}
}
String getHeader(String name)
:通过请求头的名称获取请求头的值Enumeration getHeaderNames()
:获取所有的请求头名称package com.example.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;
@WebServlet(name = "RequestDome2", value = "/RequestDome2")
public class RequestDome2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Enumeration getHeaderNames():获取所有的请求头名称
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
//String getHeader(String name):通过请求头的名称获取请求头的值
String value = request.getHeader(name);
System.out.println(name + "---" + value);
}
}
}
获取请求体数据:
请求体:只有POST请求方式,才有请求体,在请求体封装了POST请求的请求参数
步骤:
获取流对象
BufferedReader getReader()
:获取字符输入流,只能操作字符数据package com.example.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.BufferedReader;
import java.io.IOException;
@WebServlet(name = "RequestDome4", value = "/RequestDome4")
public class RequestDome4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//BufferedReader getReader():获取字符输入流,只能操作字符数据
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine())!=null){
System.out.println(line);
}
reader.close();
}
}
ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据
再从流对象中拿数据
获取请求参数的通用方式:不论get还是po请求方式都可以使用下列方法来获取请求参数
String getParameter(String name)
:根据参数名称获取参数值 username=zs&password=123
String[] getParameterValues(String name)
:根据参数名称获取参数值的数组 hobby=xx&hobby=game
Enumeration
:获取所有请求的参数名称
Map
:获取所有参数的map集合
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<form action="/Servlet_war_exploded/RequestDome3" method="post">
用户名:<input type="text" name="username">
密码:<input type="text" name="password">
<input type="checkbox" name="habby" value="game">游戏
<input type="checkbox" name="habby" value="study">学习
<input type="submit">
form>
body>
html>
package com.example.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;
import java.util.Map;
import java.util.Set;
@WebServlet(name = "RequestDome3", value = "/RequestDome3")
public class RequestDome3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//String getParameter(String name):根据参数名称获取参数值
String username = request.getParameter("username");
System.out.println(username);
System.out.println("---------");
//String[] getParameterValues(String name):根据参数名称获取参数值的数组
String[] habbies = request.getParameterValues("habby");
for (String habby : habbies) {
System.out.println(habby);
}
System.out.println("---------");
//Enumeration getParameterNames():获取所有请求的参数名称
Enumeration parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
String parameter = request.getParameter(name);
System.out.println(name);
System.out.println(parameter);
System.out.println("---------");
}
//Map getParameterMap():获取所有参数的map集合
Map parameterMap = request.getParameterMap();
Set strings = parameterMap.keySet();
for (String string : strings) {
System.out.println(string);
String[] values = parameterMap.get(string);
for (String value : values) {
System.out.println(value);
}
System.out.println("-----------");
}
}
}
request.setCharacterEncoding("utf-8");
请求转发:一种在服务器内部的资源跳转方式
RequestDispatcher getRequestDuspatcher(String path)
forward(ServletRequest rrequest,ServletResponse response)
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
void setAttribute(String name,Object obj)
:存储数据Object getAttribute(String name)
:通过键获取值void removeAttribute(String name)
:通过键移除键值对ServletContext getServletContext()
用户登录案例需求:
编写login.html登录页面
username
& password
两个输入框
使用Druid数据库连接池技术,操作mysql,day14数据库中user表
使用JdbcTemplate技术封装JDBC
登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您
登录失败跳转到FailServlet展示:登录失败,用户名或密码错误
分析:
login页面
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<form method="post" action="/Servlet_war_exploded/login">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit">
form>
body>
html>
JDBC工具类
package com.example.utils;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DruidUtils {
private static DataSource ds;
static {
//创建集合对象
Properties properties = new Properties();
//读取配置文件
InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("Druid.properties");
try {
properties.load(resourceAsStream);
try {
ds = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//获取连接方法
public static Connection getConnection() {
Connection connection = null;
try {
connection = ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return connection;
}
//释放资源方法
public static void close(Statement statement,Connection connection){
if (statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(ResultSet rs,Statement statement, Connection connection){
if (rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//获取连接池对象
public static DataSource getDataSource(){
return ds;
}
}
Dao层访问数据库
package com.example.Dao;
import com.example.domain.User;
import com.example.utils.DruidUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
public class userDao {
//定义方法获取查询出的user对象
public User getUser(User user){
try {
JdbcTemplate jdbcTemplate = new JdbcTemplate(DruidUtils.getDataSource());
String sql = "select * from user where username = ? and password = ?";
User user1 = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(User.class), user.getUsername(), user.getPassword());
return user1;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
LoginServlet获取数据调用数据层访问数据
package com.example.Request;
import com.example.Dao.userDao;
import com.example.domain.User;
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;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式
req.setCharacterEncoding("utf-8");
//获取数据
String username = req.getParameter("username");
String password = req.getParameter("password");
//封装为一个对象
User user = new User();
user.setUsername(username);
user.setPassword(password);
//调用方法查询数据
userDao userDao = new userDao();
User user1 = userDao.getUser(user);
if (user1!=null){
req.setAttribute("user",user1);
req.getRequestDispatcher("/success").forward(req,resp);
}else {
req.getRequestDispatcher("/fail").forward(req,resp);
}
}
}
SuccessServlet接受共享数据响应信息
package com.example.Request;
import com.example.domain.User;
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;
@WebServlet("/success")
public class SuccessServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
User user = (User) req.getAttribute("user");
resp.getWriter().print(user.getUsername()+"登录成功");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
FailServlet给出错误的提示信息
package com.example.Request;
import com.example.Servlet.HelloServlet;
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;
@WebServlet("/fail")
public class FailServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("登录失败");
}
}
BeanUtils工具类,简化数据封装
JavaBean:标准的Java类
概念:
成员变量:
属性:setter和getter方法截取后的产物
例如:getUsername() --> Username --> username
方法:
setProperty()
:设置指定变量名属性getProperty()
:获取指定变量名的值populate(Object obj,Map map)
:将map集合的键值对信息,封装到对应额JavaBean对象中功能:设置响应消息
HTTP/1.1 200 ok
setStatus(int sc)
setHeader(String name,String value)
PrintWriter getWriter()
ServletOutputStream getOutputStream()
重定向:资源跳转的方式
代码实现:
//1.设置状态码为302
response.setStatus(302);
//2.设置响应头localtion
response.setHeader("location","/day15/responseDemo2");
//简单的重定向方法
response.sendRedirect("/day15/responseDemo2");
重定向的特点:redirect
转发的特点:forward
路径写法
步骤:
注意:
乱码问题:
Printwriter pw = response.getwriter();
获取流的默认编码是ISO-8859-1//简单的形式,设置编码,是在获取流之前设置
response.setContentType("text/html;charset=utf-8");
package com.example.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.BufferedReader;
import java.io.IOException;
@WebServlet(name = "RequestDome5", value = "/RequestDome5")
public class RequestDome5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//response.sendRedirect("/RequestDome4");
response.getWriter().writer("模拟号");
}
}
步骤:
package com.example.Request;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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.nio.charset.StandardCharsets;
@WebServlet(name = "RequestDome6", value = "/RequestDome6")
public class RequestDome6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write("你好呀".getBytes("utf-8"));
}
}
package com.example.Response;
import javax.imageio.ImageIO;
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.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/checkCodeServlet")
public class ResponseDome extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//宽度
int width = 100;
int height = 50;
//创建对象,在内存中生成一个图片(验证码图片对象)
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//美化图片
Graphics graphics = image.getGraphics();//画笔对象
graphics.setColor(Color.PINK);
graphics.fillRect(0,0,width,height);
//画边框
graphics.setColor(Color.blue);
graphics.drawRect(0,0,width-1,height-1);
//写验证码
//定义验证码都有那些字符
String s = "QWERTYUIOPASDFGHJKLZCXVBNMqwertyuiopasdfghjklzxcvbnm123456789";
//创建随机数对象产生随机数作为角标获取字符串中的字符作为验证码
Random r = new Random();
for (int i = 1; i <=4; i++) {
int index = r.nextInt(s.length());
char c = s.charAt(index);
graphics.drawString(c+"",width/5*i,height/2);
}
//画线
graphics.setColor(Color.green);
//生成坐标
//画10条线循环10次
for (int i = 0;i<10;i++){
int w1 = r.nextInt(width);
int w2 = r.nextInt(width);
int h1 = r.nextInt(height);
int h2 = r.nextInt(height);
graphics.drawLine(w1,h1,w2,h2);
}
//将图片输出到页面
ImageIO.write(image,"jpg",resp.getOutputStream());
}
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script>
//点击图片就换一张
window.onload = function (){
//获取图片对象绑定单击事件
let img = document.getElementById("img");
img.onclick = function () {
var date = new Date();
let time = date.getTime();
img.src = "/Servlet_war_exploded/checkCodeServlet?"+time;
}
//获取a标签的对象点击换一张图片
let a = document.getElementById("code");
a.onclick = function () {
var date = new Date();
let time = date.getTime();
img.src = "/Servlet_war_exploded/checkCodeServlet?"+time;
}
}
script>
head>
<body>
<img id="img" src="/Servlet_war_exploded/checkCodeServlet">
<a id="code" href="javascript:void(0)">看不清楚?换一张a>
body>
html>
概念:代表整个web应用,可以和程序的容器(服务器)来通信
获取:
通过request对象获取
request.getServletContext();
通过HttpServlet
获取
this.getServletContext();
功能:
获取MIME类型:
String getMimeType(String file);
域对象:共享数据
setAttribute(String name,Object value)
:存储指定名称的数据getAttribute(String name)
:获取指定名称的数据removeAttribute(String name)
:删除指定名称的数据ServletContext
对象范围:所有用户所有请求的数据获取文件的真实(服务器)路径
String getRealPath(String path)
String b = context.getRealPath("/b.txt");//web目录下资源访问
System.out.println(b);
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下资源访问
System.out.println(c);
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下资源访问
System.out.println(a)
文件下载需求:
分析:
content-disposition:attachment;filename=xxx
步骤:
content-disposition:attachment;filename=xxx
问题:中文文件问题
package com.example.Response;
import com.example.utils.DownLoadUtils;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/fileServlet")
public class ResponseDome2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取文件名称
String filename = req.getParameter("filename");
//获取文件真实路径
String realPath = this.getServletContext().getRealPath("/img/" + filename);
String header = req.getHeader("user-agent");
filename = DownLoadUtils.getFileName(header, filename);
//创建字节输入流读数据
FileInputStream fileInputStream = new FileInputStream(realPath);
//获取字节输出流
ServletOutputStream outputStream = resp.getOutputStream();
//获取文件类型
String mimeType = this.getServletContext().getMimeType(filename);
//设置响应头
resp.setHeader("content-type",mimeType);
resp.setHeader("content-disposition","attachment;filename="+filename);
//读取数据到页面
byte[] bytes = new byte[1024];
int len;
while ((len=fileInputStream.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
fileInputStream.close();
}
}
会话技术:一次会话中包含多次请求和响应
功能:在一次会话的范围内的多次请求间,共享数据
方式:
概念:客户端会话技术,将数据保存到客户端
使用步骤:
new Cookie(String name,String value)
response.addCookie(Cookie cookie)
Cookie[] request.getCookies()
package com.example.Cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/cookieDome1")
public class CookieDome extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("username","zhangsan");
//发送Cookie
resp.addCookie(cookie);
}
}
package com.example.Cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/cookieDome2")
public class CookieDome2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Cookie
Cookie[] cookies = req.getCookies();
//遍历Cookie
if(cookies!=null){
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
System.out.println(name + "---" + value);
}
}
}
}
实现原理:
setMaxAge(int seconds)
setPath(String path):
设置cookie的获取范围。默认情况下,设置当前的虚拟目录
setDomain(String path):
如果设置一级域名相同,那么多个服务器之间cookie可以共享
setDomain(".baidu.com")
,那么tieba.baidu.com
和news.baidu.com
中cookie可以共享需求:
分析:
lastTime的cookie
package com.example.Cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/cookieDome3")
public class CookieDome3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//获取cookie
Cookie[] cookies = req.getCookies();
boolean flag = false;
//遍历cookie
if (cookies!=null){
for (Cookie cookie : cookies) {
//获取cookie的名称进行比较
String name = cookie.getName();
if ("lastTime".equals(name)){
flag=true;
//给cookie重新赋值
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = simpleDateFormat.format(date);
//编码
String encode = URLEncoder.encode(format, "utf-8");
cookie.setValue(encode);
resp.addCookie(cookie);
//解码
String decode = URLDecoder.decode(cookie.getValue(), "utf-8");
resp.getWriter().write("您上次访问时间为"+decode);
}
}
}
if (cookies==null||cookies.length<=0||flag==false){
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = simpleDateFormat.format(date);
//编码
String encode = URLEncoder.encode(format, "utf-8");
Cookie cookie = new Cookie("lastTime",encode);
resp.addCookie(cookie);
resp.getWriter().write("您好,欢迎您首次访问");
}
}
}
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
获取HttpSession对象:
HttpSession session = request.getSession();
使用HttpSession对象:
Object getAttribute(String name)
存储指定名称的数据
void setAttribute(String name,Object value)
获取指定名称的数据
void removeAttribute(String name)
删除指定名称的数据
Session的实现是依赖于Cookie的
当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
默认情况下。不是
如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
session什么时候被销毁?
服务器关闭
session对象调用invalidate()
session默认失效时间 30分钟
选择性配置修改
<session-config>
<session-timeout>30session-timeout>
session-config>
session用于存储一次会话的多次请求的数据,存在服务器端
session可以存储任意类型,任意大小的数据
案例需求:
分析:
代码实现:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
login
<%=request.getAttribute("mag")==null?"":request.getAttribute("mag")%>
package com.example.session;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//获取数据
String username = req.getParameter("username");
String password = req.getParameter("password");
String code = req.getParameter("code");
//获取session中的数据
HttpSession session = req.getSession();
String yzm = (String) session.getAttribute("yzm");
session.removeAttribute("yzm");
//判断验证码是否正确
if (yzm!=null&&yzm.equalsIgnoreCase(code)){
//判断用户名或密码是否正确
if ("zhangsan".equals(username)&&"123".equals(password)){
//存储用户名数据
session.setAttribute("username",username);
resp.sendRedirect(req.getContextPath()+"/success.jsp");
}else{
//存储数据并转发到页面
req.setAttribute("mag","用户名或密码错误");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}else {
//存储数据并转发到页面
req.setAttribute("mag","验证码错误");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%=request.getSession().getAttribute("username")%>,欢迎您