目录
一、动态网页基础
1、应用程序
1.1 应用程序(application)的两种结构 *
C/S模式的应用:
client:客户端/server:服务器(端):比如: QQ, 荣耀,优点:基于TCP/IP协议传输数据,网络稳定,处理能力强。缺点:推广升级困难
B/S模式的应用:
browser:浏览器/server:服务器:各种类型的网站,企业内部的应用。
优点:在线升级。缺点:严重依赖服务器,依赖网络
1.2 B/S结构程序的工作原理
从用户的操作开始,用户在浏览器页面提交表单操作,向服务器发送请求,服务器接收并处理请求,然后把用户请求的数据(网页文件、图片、声音等等)返回给浏览器,至此一次请求完成。
2、网页分类
2.1静态网页
html页面,无法和用户进行交互。不是有动画的网页
2.2 动态网页
asp,jsp,php,py:可以和用户进行交互,是原来并不存在,根据请求的不同由动态数据生成的页面
3、Http协议
3.1 http协议概念
http:Hyper Text Transfer Protocol (超文本传输协议),将数据从万维网传输到本地浏览器的一种协议方式。
1) HTTP是基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)
2) HTTP协议通常承载于TCP协议之上
HTTP若是承载与TLS或SSL协议层之上,就成了HTTPS
3) SSL(Secure Sockets Layer 安全套接字协议,SSL)及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。传输层安全性协议(英语:Transport Layer Security,缩写作TLS)
3.2 Http工作原理
一次HTTP操作称为一个事务,具体过程分为四个步骤:
1) 首先客户机与服务器需要建立连接。 (单击某个超级链接即可)
2) 建立连接后,客户机发送一个请求给服务器。
请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
3) 服务器接到请求后,给予相应的响应信息。
响应信息格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
4) 客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。
注:如果以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,由显示屏输出。
对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以
3.3 HTTP工作特点
短连接、 无状态(无记忆)
3.4 HTTP中的URL介绍
URL,全称是UniformResourceLocator, 中文叫统一资源定位器,是互联网上用来标识某一处资源的地址。以下面这个URL为例,介绍下普通URL的各部分组成:
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
1)协议部分: “http:”为协议部分,代表该网页使用的是HTTP协议,除此之外,也有FTP协议等等,后面的” // “是分隔符。
2)域名部分:“www.aspxfans.com”为域名,也可以使用IP地址作为域名,
IP地址和域名是相互绑定的,域名后的“ : ”也是分隔符。
3)端口部分:跟在域名后的“ 8080 ” 即是端口号,端口号可以省略,若省略,则采用默认端口。
4)虚拟目录部分:/news/ 是虚拟目录,判定标准是从域名的第一个“ / ” 开始,到最后一个“ / ” 为止,都是虚拟目录,可以省略
5)文件名部分:index.asp是文件名,
①从域名后的最后一个“/”开始到“?”为止,是文件名部分。
② 如果没有“?”,则从域名后的最后一个“/”开始到“#”为止,是文件名部分
③ 如果没有“?”和“#”,那从域名后的最后一个“/”开始到结束,是文件名部分。
文件名部分可以省略 ,如果省略,则使用默认文件名
6)参数部分:index.asp?boardID=5&ID=24618&page=1是参数部分,判定标准是从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。 参数可以允许有多个参数,参数与参数之间用“&”作为分隔符
7)锚部分:name是锚部分, 从“#”开始到最后,都是锚部分。 可以省略
3.5HTTP请求的方法
HTTP请求由 请求行(request line)、请求头部(header)、请求体组成
1)GET 获取资源:
①通过地址栏传输数据,安全性差,对数据有限制,2k;
②基于form表单发起或基于url发起
2)POST 向服务器端发送数据,传输实体主体
封装成数据包,内部发送,安全性高,对数据没有限制。
3)PUT 传输文件
4)HEAD 获取报文首部
5)DELETE 删除文件
6)OPTIONS 询问支持的方法
7)TRACE 追踪路径
3.6HTTP状态码
类别 | 说明 |
---|---|
1XX | Informational(信息性状态码):表示请求已接收,继续处理 |
2XX | Success(成功状态码):表示请求已经被成功接收、理解、接受 |
3XX | Redirection(重定向):要完成请求必须进行更进一步的操作 |
4XX | Client Error(客户端错误状态码):请求有语法错误或请求无法实现 |
5XX | Server Error(服务器错误状态吗):服务器未能实现合法的请求 |
容易出现的错误及错误原因:
4XX:客户端错误
400(Bad Request) :请求报文语法错误
401 (unauthorized) :需要认证
403(Forbidden) :服务器拒绝访问对应的资源
404(Not Found) :服务器上无法找到资源
405 get请求 post请求
5XX:服务器错误
500(Internal Server Error)服务器故障
503(Service Unavailable) 服务器处于超负载或正在停机维护
4、Tomcat介绍
tomcat官网:https://tomcat.apache.org
可以下载压缩包,解压即可用,是基于jdk路径的使用方法
Tomcat 服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,tomcat实现了javaEE的规范,同时也是servlet运行的环境。以下是tomcat的目录及其作用:
目录 | 描述 |
---|---|
/bin | 存放Windows平台及Linux平台上启动和关闭Tomcat的脚本文件(都是可以运行的,以sh结尾的都是Linux的脚本) |
/lib | 存放Tomcat服务器以及所有Web应用都能访问的JAR文件,也就是jar包 |
/conf | 存放Tomcat服务器的各种配置文件,其中最重要的配置文件是server.xml |
/logs | 存放Tomcat的日志文件,可以删除 |
/temp | 临时文件,可以删除 |
/webapps | 默认的Web应用文件的存放目录 |
/docs | Tomcat文档 |
/example | 示例程序 |
/work | Jsp文件编译后的servlet文件存放 |
4.1tomcat安装及问题解决
本次安装是使用的tomcat9压缩包(注意存放路径不要有中文,容易出现乱码,或编码格式无法解码的情况):
①解压后,点击运行bin目录下的startup.bat文件,
②如果出现的命令提示符(黑窗口)中出现乱码,则打开conf目录下的logging.properties文件,将第51行的utf-8改为GBK,保存后退出。
③再次点击startup.bat文件,不要关闭,去浏览器输入localhost:8080,如果能跳转到Apache tomcat的页面,就是安装成功。
注:如果出现命令提示符闪退情况,检查自己的环境变量是否有误,上网搜
如果端口号被占用,打开命令提示符
1–> netstat -ano|findstr 8080 找到占用端口的进程
2–>taskkill -pid xxx /f 终止占用端口的进程
5、创建JavaWeb工程
5.1创建步骤
①先创建一个java项目(project)
②右键点击新建项目,选择 Add Framework Support… 添加框架支持
③选择框架中的 web Application(4.0)
④完成后,点击idea主界面右上角新生成的 Add Configuration
⑤在弹出框中点击+号,选择Tomcat server 下的 local,不要错选成TomEE
⑥选择Tomcat Home(选到bin的上一级目录即可)
⑦After launch处选择默认浏览器
⑧点击弹出框下面的Fix,选择一个Web项目应用该框架,然后OK
⑨ 点击左下侧或上面工具栏中的绿三角箭头运行,若出现
Connected to server
[2022-08-08 10:09:34,167] Artifact web01:war exploded: Artifact is being deployed, please wait...
[2022-08-08 10:09:34,631] Artifact web01:war exploded: Artifact is deployed successfully
[2022-08-08 10:09:34,631] Artifact web01:war exploded: Deploy took 464 milliseconds
说明服务器启动成功,此时就能看见项目首页
5.2 web应用的目录结构
1)WEB-INF
①classes:存放java类
②lib:存放外部jar包
③web.xml文件:存放配置文件
2)META-INF
存放额外的配置文件(连接池)
3)网页文件
xxx.jsp文件
5.3运行jsp文件
1)编写内容是在.jsp文件中body中编写。
2)在web.xml文件中,可以选择此次运行的文件,如果不选择,默认运行index.jsp文件。下面是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_4_0.xsd"
version="4.0">
<!--此处为添加的内容-->
<!--默认的是index.jsp、index.html、index.htm、index.asp-->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
注:在运行文件时,选择Update classes and resources,可以直接在修改.jsp文件中的内容后自动更新,运行后在页面刷新即可完成更新。
6、创建servlet
Servlet(Server Applet)是Java Servlet的简称,是服务器的处理程序,用来处理客户端发送过来的请求的。本质上就是一个java类,继承自HttpServlet。侧重于:数据的处理
1)在创建servlet类之前,需要先导入 Tomcat中lib目录下的servlet-api.jar和jsp-api.jar包
2)2022版idea有以下两种方法创建servlet类:
第一种:
①创建一个java类
②手动继承HttpServlet,重写其中的doGet方法和doPost方法,并为其指明路径
第二种:
①点击左上角file,选择其中的project structure
②选择modules模块,点击第二列的项目名,
③选中项目名下的web项目,勾选中最底下的source Roots 然后ok
④再次新建类时,就有了servlet选项
6.1案例
//src路径下创建的包
//util包下的BaseDao(常用)
public class BaseDao {
public static final String URL="jdbc:mysql://localhost:3306/test_zzz_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true";
public static final String USER = "用户名";
public static final String PASS = "密码";
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static Connection getConcation(){
Connection connection = null;
try {
connection = DriverManager.getConnection(URL, USER, PASS);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return connection;
}
public static void setParam(PreparedStatement preparedStatement,Object... obj){
if (obj!=null){
for (int i = 0; i < obj.length; i++) {
try {
preparedStatement.setObject(i+1,obj[i]);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
public static void closeAll(ResultSet resultSet,PreparedStatement preparedStatement,Connection connection){
if (resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
System.out.println("关闭了resultSet");
}
if (preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
System.out.println("关闭了preparedStatement");
}
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
System.out.println("关闭了connection");
}
public static int addOrUpdate(String sql,Object... obj){
int i = -1;
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection=getConcation();
preparedStatement = connection.prepareStatement(sql);
setParam(preparedStatement,obj);
i = preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
closeAll(null,preparedStatement,connection);
return i;
}
public static List<Map<String,Object>> query(String sql,Object... obj){
List<Map<String,Object>> mapList = new ArrayList<>();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = getConcation();
preparedStatement = connection.prepareStatement(sql);
setParam(preparedStatement,obj);
resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
while(resultSet.next()){
Map<String,Object> map = new HashMap<>();
for (int i = 0; i < columnCount; i++) {
String columnLabel = metaData.getColumnLabel(i+1);
map.put(columnLabel,resultSet.getObject(i+1));
}
mapList.add(map);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
closeAll(resultSet,preparedStatement,connection);
return mapList;
}
}
//test包下的Test(此案例仅做测试用)
public static void main(String[] args) {
IBookDao iBookDao = new BookDaoImpl();
List<Map<String, Object>> all = iBookDao.findAll();
System.out.println(all);
}
//entity包下的实体类(Book)(此案例未用到)
public class Book {
}
//dao包下的接口(IBookDao) 以及 接口的实现类(BookDaoImpl)
public interface IBookDao {
List<Map<String,Object>> findAll();
}
public class BookDaoImpl extends BaseDao implements IBookDao {
@Override
public List<Map<String, Object>> findAll() {
String sql = "select * from book";
List<Map<String, Object>> query = query(sql);
return query;
}
}
//controller包下的servlet类
//抑制警告
@SuppressWarnings("all")
//WebServlet有一个名字,后面必须要加上要访问的路径,同时在tomcat(右上角)中的url中添加该路径
//@WebServlet(name = "MyFristServlet",value = "/Myservlet") //value和urlPatterns是相同的效果
@WebServlet(name = "MyFristServlet",urlPatterns = "/Myservlet")
//此处的Myservlet要填到编辑器的url路径中
//如果不能在new里面创建,可以在这里继承HttpServlet,然后重写doGet和doPost方法,也是一样的效果
public class MyFristServlet extends HttpServlet {
// 接收get请求的
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//实现数据库信息接口
IBookDao iBookDao = new BookDaoImpl();
//通过调用实现类中的方法获取数据库中所有的信息
List<Map<String, Object>> all = iBookDao.findAll();
//resp是response:响应,回应的意思
// 设置此次响应时,文件编码格式为GBK,保证中文不会出现乱码,
// 这里声明一定要在getWriter方法之前。
resp.setCharacterEncoding("GBK");
//获取输出的方法对象
PrintWriter writer = resp.getWriter();
//浏览器页面打印表格,先创建表头
writer.print("<table border='1'> " +
"<tr><td>id</td><td>bookname</td><td>price</td><td>author</td></tr>");
//获取表格中数据对象的个数,用于确定创建表格的行数
int size = all.size();
for (int i = 0; i < size; i++) {
writer.print("<tr>");
writer.print("<td>"+all.get(i).get("id")+"</td>");
writer.print("<td>"+all.get(i).get("bookname")+"</td>");
writer.print("<td>"+all.get(i).get("price")+"</td>");
writer.print("<td>"+all.get(i).get("author")+"</td>");
writer.print("</tr>");
}
writer.print("</table>");
//刷新writer流
writer.flush();
//关闭writer流
writer.close();
}
//接收post请求的
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
完成后的界面如下(lib的位置不要放错):
6.2修改名字
右上角点击Tomcat处的编辑器,需要修改三个地方
①server下的url路径中的名字
②deployment下的名字
③deployment下的Application context中的名字