JavaWeb动态Web资源开发
- 静态Web: 用户看到的数据始终不变;动态Web:各人看到的信息不同
- 动态Web:1.页面动态展示,淘宝"千人千面";2.和数据库交互
Web应用程序:给浏览器访问的程序 = 静态Web+动态Web
浏览器访问网络资源流程图
-
客户端通过网络协议(如Http),请求进入服务器,
-
WebSeervice收到请求,其中的**WebServerPlugin(服务插件)**判断要访问的文件是静态还是动态的.
-
静态直接找到资源文件(FIle System),动态的经过jsp,servlet(web技术)增强后(比如用jdbc连接数据库),
-
再通过WebServer(Web服务)找到对应的资源文件,然后以一种编码格式,响应回给客户端.
Http:基于Tcp的超文本传输协议
-
http使用80端口;https使用443端口,s指的是SSL/TLS协议,在HTTP和TCP/IP协议中间
-
http2.0=http/1.1版本,允许客户端与服务器连接后,获得多个资源.1.0是只能获取一个资源
请求行
- post:参数,大小没有限制,浏览器url栏不显示数据,安全,但get比它更高效
消息头(请求头):告诉服务器怎样响应你这个请求
Accept: */* 你这个请求的数据类型
Accept-Encoding: gzip, deflate, br 编码格式
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 语言环境
cache-control: max-age=0 缓存控制,最大缓存存活时间
Connection: keep-alive 连接成功后的持久策略,keep-alive始终保持连接
Host: www.dealctr.com 主机信息
响应行(响应头):告诉客户端(浏览器)应该怎样接收数据
reFresh :告诉客户端,多久刷新一次
location :网页是否重新定位
响应状态码
200:请求响应成功
300:请求重定向
404:找不到资源
500:服务器代码错误.502:网关错误
思考:浏览器从输入网址回车,到页面展示回来,经历了什么
Web服务器
服务器是一种被动的操作,处理请求与给用户回复响应
-
微软windows自带IIS服务器.
-
Tomcat是一款先进,稳定,免费的轻量级应用服务器
Tomcat
重新部署项目是重新加载当前一个项目.
-
java的根加载器在r(runtiem)t.jar包里.
-
启动startup.bat后,Tomcat的默认网址是http://localhost:8000/
-
conf下的server.xml文件是tomcat的配置文件,可以在里面修改初始参数,如端口号
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
一个webapps文件夹,就是一个Web应用
- webapps(Web项目)\ROOT下的index.jsp是默认访问的主页面:localhost:8080/index.jsp
浏览器访问网站流程
- 输入网址后,先去C:\Windows\System32\drivers\etc\hosts文件中找,有没有网址对应的域名映射(如下面的activate.navicat.com).
- 找到后返回对应的ip地址(activate.navicat.com对应的是127.0.0.1)
- 这个地址中有我们需要的web程序,找到后直接访问.
- 如果没有找到,就去**DNS(运营商根服务器)**上找,找的到就返回,找不到就提示"404(not found)找不到资源"
改变本机ip地址访问前缀:修改C:\Windows\System32\drivers\etc\hosts中的127.0.0.1(本地ip地址)的映射网址.
# 设置本机的ip地址中的,127.0.0.1和LiChangGe127.0.0.1的,映射域名为activate.navicat.com
127.0.0.1 LiChangGe127.0.0.1 activate.navicat.com
127.0.0.1 LiChangGe
# 都可以用
http://activate.navicat.com:8080/
http://lichangge:8080/
如果不可以,就再修改server.xml的host属性
<Host name="LiChangGe" appBase="webapps" unpackWARs="true" autoDeploy="true"></Host>
Web项目结构
-
一个常见的TomcatWeb项目基本结构如下:webapps(项目顶级目录)\ROOT(自己的web项目)+index.jsp\WEB-INFO(web程序配置信息目录)\web.xml(web程序配置文件)
-
Tomcat的examples是官方API包
Maven项目架构管理工具
- 核心思想:约定大于配置
idea可以不配置环境变量,自带maven
# 查看maven版本
C:\Users\林木>mvn -version
Apache Maven 3.8.3 (ff8e977a158738155dc465c6a97ffaf31982d739)
# 环境变量配置,你自己的maven安装目录
MAVEN_HOME
D:\Maven\apache-maven-3.8.3
# maven的运行程序bin目录,用idea可以不配置
M2_HOME
D:\Maven\apache-maven-3.8.3\bin
# Path引用maven,必须有
Path
%MAVEN_HOME%\bin
-
conf\settings.xml配置maven本地仓库目录和镜像
# 本地仓库,配置后去看看C:\用户\李长歌(这里是你自己的电脑账户)\.m2(默认隐藏的),这是maven默认的本地仓库,可以删掉. <localRepository>D:\Maven\apache-maven-3.8.3\mvn_properties</localRepository> # 镜像 <mirrors> <!-- 阿里镜像配置 --> <mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> </mirrors>
idea创建MavenWeb项目
一键直达
用模板创建
maven常用的全局设置
创建新模块时选择Maven构建,实现联动父项目
添加webapp目录
添加框架支持时选择web服务,来添加web目录
一个标准的web子模块
- 必须配置工件:因为访问一个网站,必须指定一个文件夹
http://localhost:8080/xiaomi
pom.xml(Maven核心配置文件)代码解读
父类和子类模块的maven代码会联动
<groupId>com.changGe.li</groupId>
<artifactId>JavaWeb</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>XiaoMi</module>
</modules>
<name>JavaWeb</name>
<packaging>pom</packaging>
# 子类
<groupId>com.changGe.li</groupId>
<artifactId>XiaoMi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>XiaoMi Maven Webapp</name>
配置运行时的java版本信息
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
配置依赖
<!-- 配置依赖:maven会自动导入这个jar包,所需要的其他jar包 -->
<dependencies>
</dependencies>
- maven遇到配置文件,无法导出或使用时 (1条消息) Maven解决配置文件无法导出或者无法生效_ReolPurion的博客-CSDN博客
- idea的日志文件,记载了我们的错误
- bat是批处理文件,可以在里面写cmd代码
HttpServlet
需要导包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<!--注意这里是配置作用域为测试和编译时有效
不配置的话,maven打包时会把这个包也打进项目中,
就会和tomcat本身的servlet-api包冲突,报500错误等
-->
<scope>provided</scope>
</dependency>
当存储数据时,其下所有类本质是一个Map集合
继承HttpServlet(javax.servlet.http包下),需要Maven导入依赖
只要是实现了Servlet接口,就叫做Servlet小程序
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
重写方法
package com.changGe.li.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("Hello World");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
配置域名映射
<servlet>
<!--设置名字和要加载的Servlet-->
<servlet-name>he</servlet-name>
<servlet-class>com.changGe.li.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--对应he下面的Servlet的域名映射是/he,注意,一定要/(代表当前web项目,也就是localhost:8080)-->
<servlet-name>he</servlet-name>
<url-pattern>/he</url-pattern>
</servlet-mapping>
tomcat日志文件配置
Servlet原理
- 如果需要携带数据去到新页面,用request转发.
- 不携带数据,只是单纯的页面跳转或刷新,就用respons重定向(respons也可以携带参数,后面再说).
浏览器向服务器发送请求,访问的是web容器(可以理解为服务器)
-
浏览器访问的是映射,然后返回IP地址
-
客户端发送请求,到达web容器.
-
如果是第一次的话,web容器直接访问servlet,第二次和以后,就是带着请求,找servlet的对应的service方法(如doGet()和doPost()等).
-
同时web容器的respons对象,也会监听接收,来自serivice的响应.监听到数据,web容器响应给客户端
作用到代码上的执行流程
表单提交时携带请求和请求参数
- 按下submit提交表单,浏览器向action的值的地方发送请求
- 提取表单中所有有name属性的元素,把他们的值作为参数传递:如localhost:8080/Super/jsp/user.do?method=modify&uid=26
<form id="userForm" name="userForm" method="post" action="${pageContext.request.contextPath }/jsp/user.do">
<input type="hidden" name="method" value="modify">
<input type="text" name="userName" id="userName" value="${user.userName}">
<input class="button_box" type="submit" value="保存">
</form>
- 服务器找到web.xml,看有没有对应的映射
- 找到这个映射对应的servlet
<servlet>
<servlet-name>modifyPassword</servlet-name>
<servlet-class>com.changGe.li.servlets.ModifyPasswordServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>modifyPassword</servlet-name>
<!--
/ 代表当前路径,也就是localhost:8080
其后的路径语法根据表单的请求来写
也可以随便写,如/* 代表项目下所有资源都可以访问,或
-->
<url-pattern>/jsp/user.do</url-pattern>
</servlet-mapping>
<!--不能这样写,会报错java.lang.IllegalArgumentException: servlet映射中的<url pattern>[/*.do]无效
因为/*,是匹配localhost:8080/下所有servlet上,/*.do服务器就认为你要访问所有以.do为后缀的Servlet,找不到
-->
<url-pattern>/*.do</url-pattern>
- 优先访问最接近的映射
<a href="${pageContext.request.contextPath}/hello">
<!--优先访问最接近的-->
<url-pattern>/hello</url-pattern>
<!--不访问-->
<url-pattern>/hello.do</url-pattern>
-
调用对应的service(),如上面的表单提交方式是get,就找到doGet();
-
执行其中的实现代码
public class ModifyPasswordServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//重定向发送一个请求且携带参数
resp.sendRedirect(req.getContextPath()+"/jsp/user.do?method=query");
}
ServletContxet:管理所有Servlet,实现Servlet间共享数据
每个程序都有一个对应的上下文对象(ServletContext)
实现Servlet间共享数据
<servlet>
<servlet-name>he</servlet-name>
<servlet-class>com.changGe.li.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>he</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.changGe.li.servlet.TestServletOne</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello.do</url-pattern>
</servlet-mapping>
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
ServletContext servletContext = this.getServletContext();
servletContext.setAttribute("name","武则天");
}
}
public class TestServletOne extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
ServletContext servletContext = this.getServletContext();
Object name = servletContext.getAttribute("name");
System.out.println(name);
}
}
servletContext转发
// 一定要写上/代表当前web项目目录下
servletContext