1.浏览器发出http://localhost:8080/web-demo/demo1
请求,从请求中可以解析出三部分内容,分别是localhost:8080
、web-demo
、demo1
localhost:8080
可以找到要访问的Tomcat Web服务器web-demo
可以找到部署在Tomcat服务器上的web-demo项目demo1
可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配2.找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象,然后调用对象中的service方法
@WebServlet(urlPatterns = "/demo2",loadOnStartup = 1)
初始化方法
* 1.调用时机:默认情况下,Servlet被第一次访问时,调用
* loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用,数字越小优先级越高.
* 2.调用次数: 1次
init
* 初始化方法
* 1.调用时机:默认情况下,Servlet被第一次访问时,调用
* * loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用
* 2.调用次数: 1次
* @param config
* @throws ServletException
service
/**
* 提供服务
* 1.调用时机:每一次Servlet被访问时,调用
* 2.调用次数: 多次
* @param req
* @param res
* @throws ServletException
* @throws IOException
*/
destroy
/**
* 销毁方法
* 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
* 2.调用次数: 1次
*/
在HttpServlet中我们一般封装了一些方法,变量和常量 当发送不同类型的请求时-Post或者Get,我们一般需要判断来获得其中的参数等等内容,这个HttpServlet这个类进行了封装,我们只需要重写doGet和doPost两个方法即可。其中的判断继承的HttpServlet已经帮我们写好了。
继承HttpServlet
重写doGet和doPost方法
获取请求方式,并根据不同的请求方式,调用不同的doXxx方法
视频:96 --Javaweb
1.精确匹配
@WebServlet(urlPatterns={“/demo7”,“/demo8”})
小结
前面对应Servlet的配置,我们都使用的是@WebServlet,这个是Servlet从3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。
对于XML的配置步骤有两步:
demo13
com.itheima.web.ServletDemo13
demo13
/demo13
1.请求行包含三块内容,分别是请求方式
、请求资源路径
、HTTP协议及版本
GET
String getMethod()
/request-demo
String getContextPath()
http://localhost:8080/request-demo/req1
StringBuffer getRequestURL()
/request-demo/req1
String getRequestURI()
username=zhangsan&password=123
String getQueryString()
2.获取请求体数据
BufferedReader getReader()
BufferedReader reader = req.getReader();
String s = reader.readLine();
System.out.println(s);
ServletInputStream getInputStream()
该方法可以获取字节
3.请求头数据
String getHeader(String name)
//获取请求头: user-agent: 浏览器的版本信息
String agent = req.getHeader("user-agent");
System.out.println(agent);
Request获取请求参数的通用方式
-----get和Post参数获取的通用方法。//@WebServlet(urlPatterns = "*.do")
public class Servletdemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp); //核心
}
}
Map
getParameterMap()
String[] getParameterValues(String name)
String getParameter(String name)
//获取所有参数的Map集合
Map parameterMap = req.getParameterMap();
for (String s : parameterMap.keySet()) {
System.out.print(s+':');
String[] strings = parameterMap.get(s);
for (String string : strings) {
System.out.print(string);
}
System.out.println();
}
//根据名称获取参数值(数组)
String[] usernames = req.getParameterValues("username");
for (String username : usernames) {
System.out.println(username);
}
//根据名称获取参数值(单个值,会获得第一个)
String username = req.getParameter("username");
System.out.println(username);
1.按照自己的需求,修改Servlet创建的模板内容
2.创建Servlet项目
1.POST
分析出现中文乱码的原因:
解决方案:
2.Get
URL编码:
这块知识我们只需要了解下即可,具体编码过程分两步,分别是:
(1)将字符串按照编码方式转为二进制
(2)每个字节转为2个16进制数并在前边加上%
张三
按照UTF-8的方式转换成二进制的结果为:
1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001
String username = "张三";
//1. URL编码
String encode = URLEncoder.encode(username, "utf-8");
System.out.println(encode); //打印:%E5%BC%A0%E4%B8%89
//2. URL解码
//String decode = URLDecoder.decode(encode, "utf-8");//打印:张三
String decode = URLDecoder.decode(encode, "ISO-8859-1");//打印:`å¼ ä¸ `
System.out.println(decode);
GET请求中文参数出现乱码的原因
UTF-8
进行URL编码ISO-8859-1
的URL解码å¼ ä¸‰
的乱码,最后一位是个空格解决方案:
1.按照ISO-8859-1编码获取乱码
å¼ ä¸‰
对应的字节数组2.按照UTF-8编码获取字节数组对应的字符串
String username = request.getParameter("username");
byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
String s = new String(bytes, StandardCharsets.UTF_8);
System.out.println(s);
1.请求转发(forward):一种在服务器内部的资源跳转方式。
(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求
(2)资源A处理完请求后将请求发给资源B
(3)资源B处理完后将结果响应给浏览器
(4)请求从资源A到资源B的过程就叫请求转发
2.请求转发的实现方式:
req.getRequestDispatcher(“资源B路径”).forward(req,resp);
3.请求转发资源间共享数据:使用Request对象
void setAttribute(String name,Object o);
request.setAttribute(“name”,“hello”);
Object getAttribute(String name);
void removeAttribute(String name);
Response重定向(redirect):一种资源跳转方式。
1.响应行
void setStatus(int sc);
一般设置响应状态码。
2.响应头
void setHeader(String name,String value);
3.响应体
获取字符输出流: PrintWriter getWriter();
获取字节输出流:ServletOutputStream getOutputStream();
//重定向
//1.设置响应状态码 302
response.setStatus(302);
//设置响应头 Location
response.setHeader("Location","/request-demo/resp2");
//2.简化版本
resposne.sendRedirect("/request-demo/resp2")
resp.setStatus(302);
resp.setHeader("location","资源B的访问路径");
---重定向的简化方式
resposne.sendRedirect("/request-demo/resp2");
判断依据:
- ` 超链接,从浏览器发送,需要加
- `
1.响应字符数据
一般为文字等等
1.返回一串html字符串,并且能被浏览器解析 并且能够解析中文
response.setContentType(“text/html;charset=utf-8”);
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("哈哈");
writer.write("哈哈
");
中文乱码问题:
response.setContentType("text/html;charset=utf-8");
2.响应字节数据
为文件和图片等等
//1. 读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
//3. 完成流的copy
byte[] buff = new byte[1024];
int len = 0;
while ((len = fis.read(buff))!= -1){
os.write(buff,0,len);
}
fis.close();
对于流的copy的代码还是比较复杂的,所以我们可以使用别人提供好的方法来简化代码的开发,具体的步骤是:
1.pom.xml添加依赖
commons-io
commons-io
2.6
2.调用工具类方法
//fis:输入流
//os:输出流
IOUtils.copy(fis,os);
实现代码
FileInputStream fis = new FileInputStream("C://Users//Administrator//Desktop//aaa.jpg");
ServletOutputStream os = response.getOutputStream();
IOUtils.copy(fis,os);
初始开发环境
dependencies
标签中导入 JSP 的依赖,如下
javax.servlet.jsp
jsp-api
2.2
provided
webapp
下创建jsp页面JSP 本质上就是一个 Servlet , 其中html的代码转换成如下形式。
而Java代码直接显示。
JSP 脚本有如下三个分类:
<%
System.out.println(“hello,jsp~”);
int i = 3;
%>
<%=“hello”%>
<%=i%>
<%!
void show(){}
String name = “zhangsan”;
%>
<%@ page import="com.itheima.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 查询数据库
List brands = new ArrayList();
brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
%>
Title
序号
品牌名称
企业名称
排序
品牌介绍
状态
操作
<%
for (int i = 0; i < brands.size(); i++) {
Brand brand = brands.get(i);
%>
<%=brand.getId()%>
<%=brand.getBrandName()%>
<%=brand.getCompanyName()%>
<%=brand.getOrdered()%>
<%=brand.getDescription()%>
<%=brand.getStatus() == 1 ? "启用":"禁用"%>
修改 删除
<%
}
%>
由于 JSP页面内,既可以定义 HTML 标签,又可以定义 Java代码,造成了以下问题:
书写麻烦:特别是复杂的页面,既要写 HTML 标签,还要写 Java 代码
阅读麻烦,上面案例的代码,相信你后期再看这段代码时还需要花费很长的时间去梳理
复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…
占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
调试困难:出错后,需要找到自动生成的.java文件进行调试
不利于团队协作:前端人员不会 Java,后端人员不精 HTML
如果页面布局发生变化,前端工程师对静态页面进行修改,然后再交给后端工程师,由后端工程师再将该页面改为 JSP 页面
EL(全称Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码。
EL 表达式的主要作用是 获取数据。其实就是从域对象中获取数据,然后将数据展示在页面上。
而 EL 表达式的语法也比较简单, ${expression}
。例如:${brands} 就是获取域中存储的 key 为 brands 的数据。
例如:
1. @WebServlet("/Servletdemo3")
//1. 准备数据
List brands = new ArrayList();
brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
request.setAttribute("brands",brands);
request.getRequestDispatcher("/hello.jsp").forward(request,response);
2.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
hello jsp
<%= "hello world"%>
${brands}
JavaWeb中有四大域对象,分别是:
el 表达式获取数据,会依次从这4个域中寻找,直到找到为止。而这四个域对象的作用范围如下图所示
例如: ${brands},el 表达式获取数据,会先从page域对象中获取数据,如果没有再到 requet 域对象中获取数据,如果再没有再到 session 域对象中获取,如果还没有才会到 application 中获取数据。
JSP标准标签库(Jsp Standarded Tag Library) ,使用标签取代JSP页面上的Java代码。如下代码就是JSTL标签
使用前提导入内容:
jstl
jstl
1.2
taglibs
standard
1.1.2
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
1.if 标签
男
女
2.forEach 标签
1.类似于 Java 中的增强for循环。涉及到的
中的属性如下
从域对象中获取名为 brands 数据,该数据是一个集合;遍历遍历,并给该集合中的每一个元素起名为 brand
,是 Brand对象。在循环里面使用 EL表达式获取每一个Brand对象的属性值
-- <%--其中这个brand.id为直接通过id-----Id +get 去寻找这个方法获得数据--%>---
<%-- ${brand.id} --%>
${status.count} ------------获取从一到后面的数字
${brand.brandName}
${brand.companyName}
${brand.ordered}
${brand.description}
启用
禁用
修改 删除
2.类似于 Java 中的普通for循环。涉及到的
中的属性如下
${i}
1.MVC
MVC 是一种分层开发的模式,其中:
M:Model,业务模型,处理业务
V:View,视图,界面展示
职责单一,互不影响。每个角色做它自己的事,各司其职。
有利于分工协作。
有利于组件重用
注册业务功能
,我们会先调用 数据访问层
的 selectByName()
方法判断该用户名是否存在,如果不存在再调用 数据访问层
的 insert()
方法进行数据的添加操作而整个流程是,浏览器发送请求,表现层的Servlet接收请求并调用业务逻辑层的方法进行业务逻辑处理,而业务逻辑层方法调用数据访问层方法进行数据的操作,依次返回到serlvet,然后servlet将数据交由 JSP 进行展示。
三层架构的每一层都有特有的包名称:
com.itheima.controller
或者 com.itheima.web
com.itheima.service
com.itheima.dao
或者 com.itheima.mapper
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
Cookie的操作主要分两大类,本别是发送Cookie和获取Cookie
1.发送Cookie
Cookie cookie = new Cookie(“key”,“value”);
response.addCookie(cookie);
2.获取Cookie
Cookie[] cookies = request.getCookies();
cookie.getName();
cookie.getValue();
//获取Cookie
//1. 获取Cookie数组
Cookie[] cookies = request.getCookies();
//2. 遍历数组
for (Cookie cookie : cookies) {
//3. 获取数据
String name = cookie.getName();
if("username".equals(name)){
String value = cookie.getValue();
System.out.println(name+":"+value);
break;
}
}
Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:
setMaxAge(int seconds)
参数值为:
1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
3.零:删除对应Cookie
//发送Cookie
//1. 创建Cookie对象
Cookie cookie = new Cookie("username","zs");
//设置存活时间 ,1周 7天
cookie.setMaxAge(60*60*24*7); //易阅读,需程序计算
//cookie.setMaxAge(604800); //不易阅读(可以使用注解弥补),程序少进行一次计算
//2. 发送Cookie,response
response.addCookie(cookie);
A发送Cookie
//发送Cookie
String value = "张三";
//对中文进行URL编码
value = URLEncoder.encode(value, "UTF-8");
System.out.println("存储数据:"+value);
//将编码后的值存入Cookie中
Cookie cookie = new Cookie("username",value);
//设置存活时间 ,1周 7天
cookie.setMaxAge(60*60*24*7);
//2. 发送Cookie,response
response.addCookie(cookie);
----------------------------------------------------------
B接受Cookie
//获取Cookie
//1. 获取Cookie数组
Cookie[] cookies = request.getCookies();
//2. 遍历数组
for (Cookie cookie : cookies) {
//3. 获取数据
String name = cookie.getName();
if("username".equals(name)){
String value = cookie.getValue();//获取的是URL编码后的值 %E5%BC%A0%E4%B8%89
//URL解码
value = URLDecoder.decode(value,"UTF-8");
System.out.println(name+":"+value);//value解码后为 张三
break;
}
}
Session:服务端会话跟踪技术:将数据保存到服务端。
在JavaEE中提供了HttpSession接口,来实现一次会话的多次请求之间数据共享功能。
HttpSession session = request.getSession();
1.存储数据到 session 域中
void setAttribute(String name, Object o)
2.根据 key,获取值
Object getAttribute(String name)
3.根据 key,删除该键值对
void removeAttribute(String name)
A: 存储数据
//存储到Session中
//1. 获取Session对象
HttpSession session = request.getSession();
//2. 存储数据
session.setAttribute("username","zs");
B:获取数据
//1. 获取Session对象
HttpSession session = request.getSession();
//2. 获取数据
Object username = session.getAttribute("username");
System.out.println(username);
Session是基于Cookie实现的
1.Set-Cookie:JESSIONID=10
到响应头中,并响应给浏览器
2.浏览器接收到响应结果后,会把响应头中的coookie数据存储到浏览器的内存中
3.cookie: JESSIONID=10的格式添加到请求头中并发送给服务器Tomcat
4.从请求头中就读取cookie中的JSESSIONID值为10,然后就会到服务器内存中寻找id:10
的session对象,如果找到了,就直接返回该对象,如果没有则新创建一个session对象
5.关闭打开浏览器后,因为浏览器的cookie已被销毁,所以就没有JESSIONID的数据,服务端获取到的session就是一个全新的session对象
1.Session钝化与活化:
钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中
钝化的数据路径为:`项目目录\target\tomcat\work\Tomcat\localhost\项目名称\SESSIONS.ser
活化:再次启动服务器后,从文件中加载数据到Session中
数据加载到Session中后,路径中的
SESSIONS.ser
文件会被删除掉
2.Session销毁
100
Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
1.进行 Filter
开发分成以下三步实现
package com.itheima.web.filter;
import javax.servlet.*;
import java.io.IOException;
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//放行前执行代码
filterChain.doFilter(servletRequest,servletResponse);
//放行后执行代码
}
@Override
public void destroy() {
}
}
拦截路径有如下四种配置方式:
例如:BFilterDemo
和
AFilterDemo。那一定是
AFilterDemo` 过滤器先执行
Listener 表示监听器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
监听器可以监听就是在 application
,session
,request
三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。
ServletContext
代表整个web应用,在服务器启动的时候,tomcat会自动创建该对象。在服务器关闭时会自动销毁该对象。
ServletContextListener
接口@WebListener
进行配置@WebListener
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//加载资源
System.out.println("ContextLoaderListener...");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//释放资源
}
}
启动服务器,就可以在启动的日志信息中看到 contextInitialized()
方法输出的内容,同时也说明了 ServletContext
对象在服务器启动的时候被创建了。
AJAX
(Asynchronous JavaScript And XML):异步的 JavaScript 和 XML。
有以下两方面:
.2.异步交互**:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用校验,等等…
欢迎注册
axious发送的ajax请求中的json都是json串 ,我们在java中需要将起转换成json对象 **JSON字符串转Java对象** User user = JSON.parseObject(jsonStr, User.class);
前端实现
1.get 请求
axios({
method:"get",
url:"http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan"
}).then(function (resp) {
alert(resp.data);
})
2.post 请求
axios({
method:"post",
url:"http://localhost:8080/ajax-demo/axiosServlet",
data:"username=zhangsan"
}).then(function (resp) {
alert(resp.data);
})
2.请求方法别名
为了方便起见, Axios 已经为所有支持的请求方法提供了别名。如下:
get
请求 : axios.get(url[,config])
delete
请求 : axios.delete(url[,config])
head
请求 : axios.head(url[,config])
options
请求 : axios.option(url[,config])
post
请求:axios.post(url[,data[,config])
put
请求:axios.put(url[,data[,config])
patch
请求:axios.patch(url[,data[,config])
get方法:
axios.get("http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan").then(function (resp) {
alert(resp.data);
});
post方法:
axios.post("http://localhost:8080/ajax-demo/axiosServlet","username=zhangsan").then(function (resp) {
alert(resp.data);
})
axious发送的ajax请求中的json都是json串 ,我们在java中需要将起转换成json对象
JSON字符串转Java对象
User user = JSON.parseObject(jsonStr, User.class);
JSON
的格式
{
"name":"zhangsan",
"age":23,
"city":"北京"
}
JSON
本质就是一个字符串,但是该字符串内容是有一定的格式要求的。
var 变量名 = ‘{“key”:value,“key”:value,…}’; —这是JSON串
JSON
串的键要求必须使用双引号括起来,而值根据要表示的类型确定。value 的数据类型分为如下
var jsonStr = ‘{“name”:“zhangsan”,“age”:23,“addr”:[“北京”,“上海”,“西安”]}’
基础方法
//json串
var jsonStr = '{"name":"zhangsan","age":23,"addr":["北京","上海","西安"]}' json串
var parse = JSON.parse(jsonStr); 转换成json对象
let s = JSON.stringify(parse); json对象转换成json串
Fastjson
是阿里巴巴提供的一个Java语言编写的高性能功能完善的 JSON
库,是目前Java语言中最快的 JSON
库,可以实现 Java
对象和 JSON
字符串的相互转换。
1.Fastjson 使用
com.alibaba
fastjson
1.2.62
String jsonStr = JSON.toJSONString(obj);
User user = JSON.parseObject(jsonStr, User.class);
代码演示:
User user=new User();
user.setId(1);
user.setUsername("wangwei");
user.setPassword("wangwei");
//对象转JSON
String s = JSON.toJSONString(user);
System.out.println(s);
//JSON转对象
User user1 = JSON.parseObject("{\"id\":1,\"password\":\"wangwei\",\"username\":\"wangwei\"}", User.class);
System.out.println(user1);
每一个功能都需要定义一个 servlet
,一个模块需要实现增删改查功能,就需要4个 servlet
,模块一多就会造成servlet
泛滥。此时我们就想 servlet
能不能像 service
一样,一个模块只定义一个 servlet
,而每一个功能只需要在该 servlet
中定义对应的方法。
@WebServlet("/brand/*")
public class BrandServlet {
//查询所有
public void selectAll(...) {}
//添加数据
public void add(...) {}
//修改数据
public void update(...) {}
//删除删除
public void delete(...) {}
}
servlet
,tomcat
会自动的调用 service()
方法,之前我们在自定义的 servlet
中重写 doGet()
方法和 doPost()
方法,当我们访问该 servlet
时会根据请求方式将请求分发给 doGet()
或者 doPost()
方法
如下图: