Java Web
基础概念
web开发:
- web–网页
- 静态web
- html, css…
- 提供给所有人看不会发生变化的.
- 动态web
- 京东…几乎所有的网站
- 提供的数据始终在变化,每个人看到的都不相同
- 技术栈:Servlet/jsp, asp, php
在java中,动态web资源开发的技术统称javaweb
web应用程序:
- 可以提供浏览器访问的程序,例如abc.html…
- 我们每一个访问的页面或资源,都存在于世界上某一个角落的计算机上
- 这个统一的web资源会被放在同一个文件夹下,web应用程序–>Tomcat:服务器
- 一个web应用由多部分组成 (静态web,动态web)
- html,css,js
- jsp,servlet
- Java程序
- jar包,配置文件 (Properties)…
静态web:
*.htm/ *.html这些都是网络后缀,需要一个统一的服务器管理;
缺点:除了不能动,不能更新,没有特效,无法跟数据库交互,无法跟用户交互几乎没有缺点.
动态web:
缺点:当动态资源出现问题时,我们需要重新编写我们的后台程序,重新发布;(停机维护)
web服务器(实现手段)
ASP:
- 微软: 国内最早流行的
- 在html中嵌入VB脚本
- 在ASP开发中,基本上一个页面上有html,java,css等代码,全部嵌套在一起
- 主要应用c#语言,维护成本高,iis服务器
PHP:
- 开发速度快,功能强大,跨平台,代码简单(优点)
- 无法承载大访问量的情况–中小型开发(缺点)
JSP(Servlet):
- sun公司主推的B/S架构
- 基于java语言开发(几乎所有大公司都用java)
- 可以解决高并发,高可用,高性能(三高问题)
搭建Web环境
c/s架构与b/s架构
- c/s架构需要有客户端才能进行操作,需要进行更新等
- b/s架构只需要打开浏览器就可以直接操作
- b/s架构原理:基于请求与响应–客户发送请求信息,服务器运行程序返回检索到的信息
随着5G时代的到来,b/s架构会更受欢迎
URL
http://www.bdqn.cn/news/200/newslist.jsp?page=6
其中:
- http 是协议
- www.bdqn.cn 是主机地址
- /news/200/newslist.jsp 是目标资源地址
- ?page=6 是传递的参数
URL (Uniform Resource Locator) “统一资源定位符"
万维网中统一默认端口号是80,默认协议是http,这些都是不用你直接输入的
WEB服务器
服务器是一种被动的操作,用来处理用户请求返回一些响应信息.
Web服务器可以向发出请求的浏览器提供文档的程序,以提供上网的功能(运行Web程序的)
常见的web服务器
- IIS: 微软自带服务器
- Nainx
- Apache: Tomcat
Tomcat服务器
Tomcat是由Apacha软件基金会出品,Apacha是一个专门支持开源软件的基金会.
Tomcat官网; http://tomcat.apache.or
启动:
- bin\startup.bat
- 访问Tomcat主页: http://localhost:端口号
- 关闭: bin\shutdown.bat
访问:
- 将解压好的项目放进webapps文件夹里面,必须以文件夹的形式
- 先启动Tomcat然后再在浏览器里输入localhost:8080/文件夹名
特点:
- Apache Jakarta的开源项目
- 轻量级应用服务器
- 开源,稳定,资源占用小
坑:
- 如果Tomcat运行不了,那就去配置jdk,(只能有一个jdk)
- 提示80端口被占用,那就去卸载 服务-sql sever
- 放进webapps里的文件想要打开就必须放进文件夹里
目录:
- bin : 执行与开关闭
- conf : 配置文件
- lib : 所有的jar包
- logs ; 日志文件
- temp : 临时文件
- webapps : 今后所有程序的放置位置
- work : Tomcat把由jsp生成的Servlet放于此(无意义)
小结:
-
Tomcat浏览器访问方式: localhost:8080(本地ip地址:端口号)
-
conf/sever.xml文件
-
可以更改端口号
-
可以更改主机名称
-
补充:高难度面试题:
请你谈谈网站是如何进行访问的!
-
输入一个域名;回车
-
检查本机的 C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射;
-
有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问
127.0.1 www.linghuchong.com//在hosts文件里
-
没有:去DNS服务器找,找到的话就返回,找不到就返回找不到;
-
Http
含义
HTTP(超文本传输协议):一个简单的请求-响应协议,通常运行在Tcp之上
端口:80
HTTPS: 端口443
两个时代:
- http1.0: 客户端与web服务器连接后,只能获得一个web资源并断开连接
- http1.1: 一次可以获得多个web资源
Http请求
- 客户端 – 发请求 – 服务器
Http响应
- 服务器 – 响应 – 客户端
部署自己的web项目(idea)
视频在–第十五周–1213–视频文件夹
- 在idea里面先创建一个java项目
- 项目右键添加框架支持–web应用程序4.0
- 添加配置-汤姆猫
- 项目结构-全局库-添加进去
- // 上边栏设置按钮–工件–点击+号–web应用程序:存档–对于’…’
- // 点击最上方栏–构建–构建工件–项目名:war–构建
- // 构建完左边项目里就会出现out文件夹(里面找到war文件)
- // 将war文件放入Tomcat里的webapps文件夹,然后点击Tomcat运行,就会解压,解压成一个文件夹的形式
- 在浏览器里输入localhost:8080/项目文件夹名访问自己创建的项目
- 一个网站应该有的结构:
--webapps :Tomcat服务器的web目录
-ROOT
-linghuchong :网站的目录名
- WEB-INF-classes : java程序
-lib:web应用所依赖的jar包
-web.xml :网站配置文件
- index.html 默认的首页
- static
-css
-style.css
-js
-img-...
在idea里面配置Tomcat
- 在idea中右上角有个添加配置-- 点击+号
- 找到Tomcat服务器-本地
- 注意这里也可以进行端口号的修改
- 修改jdk,找到自己的jdk安装目录
- 在上栏找到部署 --工件–可选war包跟war exploded(扩展包)
war包跟war exploded包的区别:
-
前者是需要解压然后才能运行的, 后者不需要.一般练习用测试包就可以,这样减少资源的浪费,上传到服务器端项目的时候才会用war包
-
然后睡觉哦应用程序的上下文–这里注意小写英文字母就可以了
JSP(Java跟html的结合)
初识 jsp
JSP:(Java Server Pages)
在 JSP 文件中,HTML 代码与 Java 代码共同存在,其中,HTML 代码用来实现网页中静态内容的显 示,Java 代码用来实现网页中动态内容的显示。
特点:
- 跨平台:适用于各大主流系统平台运行
- 业务代码相分离(运行原理)
- 组件重用
- 预编译
运行原理:
一些jsp代码指令
基本结构: <% 内容 %>
<%@ **page **contentType=“text/html;charset=UTF-8” language=“java” %>
page指令:
-
用于表明这是一个jsp;
-
他用来设置JSP文件中的全局属性;
-
language=“java"声明脚本语言的种类,暂时只能用"java”.
注意:
-
在 page 指令中区分大小写,不限制指令的位置、个数,JSP 指令对整个页面有效
-
contentType主要是告诉浏览器自己是什么类型的文件,同时要求浏览器以什么编码进行解析
out 输出:
// 向页面输出
<% out.println(); %> / <% out.print(); %>
注意做到这一步会产生一个报错,具体解决的途径是导入jar包,具体步骤如下:
- 导包: 找到Tomcat安装目录–lib–找到 jsp-api.jar
- 在 idea 目录中 WEB-INF 中新建一个 lib 文件夹复制刚才的 jar 文件
- 右键点击 jar 包–添加为库
- 右侧栏–项目结构–右键点击–置于…
注意:
-
直接用上面的语句会产生一个问题-- 可读性不好(java代码与heml代码混在一起,且不利于修改)
解决方法: 声明变量,利用标签进行解决
如下:
<% String name = "张三";//声明变量 // 向页面输出 out.println("我叫"+name); %> <%="我叫"+name%>//<!--跟上面的是一样的,注意name后面不要写;-->
-
使用< %@page%>导包 如:< %@page import=“java.util.Date”%>
-
输出转义字符。 如:<%=“谈”\北京精神\ “”%>(转义字符代表的是你先使用/输出这个符号,而不是它在这里面本身的作用–这里指字符串用“”括起来。)
注释:
- HTML注释:
- JSP注释: <%–JSP注释–%>
- JSP脚本中注释<%//单行注释%> <%/* 多行注释*/%>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/12/13
Time: 10:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>Hello Web !!!</h1>
<%-- 向页面输出 谈KJDE1037学习精神--%>
<%
// 脚本 里面可以写Java代码
// int a = 10;
// if(a > 5){
// System.out.println("Hello"); // 向控制台输出
// }
String name = "张三";
// 向页面输出
out.println("谈KJDE1037学习精神");
out.println("我叫"+name);
// 输出当前日期
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String dateString = format.format(date);
out.print("当前时间是"+dateString);
%>
<%-- 向页面输出 \转义 代表你想使用的是符号本身 --%>
<%="现在时间\"是\""+dateString%>
</body>
</html>
JSP执行原理
此处省略一万字… …
局部变量与全局变量
<%
// 声明局部变量
int i = 0;
i++;
// 局部变量 : 声明在脚本的内部 每次使用都初始化
// 全局变量 声明在外部 只会在加载的时候初始化一次(每次使用都变化一次)
// out在局部可用,全局用不了,因为局部有参数,全局没有参数
%>
<!-- 声明全局变量 -->
<%! int k = 0; %>
<!-- 声明全局变量 -->
public void show(){
System.out.println("我是全局方法,我被执行了")
}
<%="局部变量"+i%>
<%="全局变量"+(k++)%>
常见错误
- 404: 地址写错了/页面没有在WEB-INF下/外部启动了Tomcat,未部署项目
- 500: jsp页面代码有错误
- … …
JSP实现数据传递和保存
一.request请求
// 获取表单数据
getParameter();
// 获取多个相同的name
getParameterValues()
// 解决中文字符乱码问题
// 设置字符编码 解决post请求,而get不会有这个问题
setCharacterEncoding()
setCharacterEncoding("utf-8")
// 存储数据 request作用域 数据只存在与一次请求只间
setAttribute(key,value)
// 获取数据 可能有空指针异常 返回值是object需要强转
Object getAttribubte(key)
// 请求转发
// forward(request,response) 是固定写法
request.getRequestDispatcher("转发地址").forward(request,response)
二.response响应
// 重定向
response.sendRedirect()
三.请求转发和重定向区别
转发 | 重定向 |
---|---|
地址栏不会发生变化 | 地址发生变化 |
请求一次 | 请求两次 |
携带请求 | 不携带请求 |
作用域web程序(不能转发到程序以外的界面) | 任意的地址(URL)都可以重定向 |
转发:
重定向:
get与post的区别
比较项 | Get | Post |
---|---|---|
参数是否出现在url(地址栏)中 | 是 | 否 |
安全性 | 低 | 高 |
URL可传播 | 是 | 否 |
长度限制 | 有 | 无 |
四.示例
登录界面
<form action="dologin.jsp" method="get">
<p>
用户名: <input type="text" name="name">
</p>
<p>
密码: <input type="password" name="pwd">
</p>
<p>
<input type="submit" value="登录">
</p>
</form>
处理请求页面
// 2.接收参数
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
// 3.验证密码是否正确
String uname = "渣渣辉";
String upwd = "123456";
if (name.equals(uname) && pwd.equals(upwd)){
// 存储数据 键值对 key value
request.setAttribute("name",name);//存储一次数据
//对应下方欢迎界面的get
// 4.进行请求转发
request.getRequestDispatcher("welcome.jsp").forward(request,response);
}else{
// 5.正常情况下密码错误 回到index.jsp
//request.getRequestDispatcher("index.jsp").forward(request,response);
// 使用重定向
response.sendRedirect("index.jsp");
欢迎界面
<%--如果没有数据会出现空指针异常所以要判空 得到的数据是object类型 所以要进行数据类型转换--%>
<h1>
欢迎你 <%= request.getAttribute("name") == null ? "" : //获取这一次值时进行判空
(String) request.getAttribute("name")%> //强转
</h1>
session
作用域: 一次会话中实现数据共享
request
作用域: 只在一次请求实现数据传递
session.getAttribute()
session.setAttribute()
// 设置有效期 和获取有效期 s:秒
session.setMaxInactiveInterval()
// 获取有效期
session.getMaxInactiveInterval()
// 清除session数据
session.invalidate();
// 删除session属性
session.removeAttribute()
// 在web.xml中设置session有效期 m:分
<session-config>
<session-timeout>1</session-timeout>
</session-config>
application
作用域: 整个web程序之间实现数据共享
application.getAttribute()
application.setAttribute()
<%
int count = 0 ;//初始化
if(application.getAttribute("count")==null){
count++;//第一次进入这个页面,给你设置为1
application.setAttribute("count",count);
}else{
//只要不是第一次进入这个页面,获取你的值,++,然后再设置
count = (int) application.getAttribute("count");
count++;
application.setAttribute("count",count);
}
%>
<h1>欢迎您能在百忙之中莅临本站,<%=count%>号客人</h1>
cookie
作用域: 以文件的形式保存数据到浏览器(客户端)中
并且只能存字符串,
// 添加cookie
response.addCookie(Cookie cookie)
// 创建cookie对象
Cookie cookie = new Cookie("key",value)
// 设置cookie有效期
cookie.setMaxAge() //s:秒
// 获取cookie
Cookie[] request.getCookie()
JDBC
Java DataBase Connectivity(Java 语言连接数据库)
-
本质
JDBC是SUN公司制定的一套接口(interface)
–原因就是因为每一个数据库都有自己的实现原理,为了方便连接数据库,方便使用跟书写代码
接口都有调用者与实现者
面向接口调用,面相接口写实现类这都属于面向接口编程
-
为什么要面向接口编程?
降低程序的耦合性,提高程序的可读性跟拓展性
多态机制就是典型的面相抽象编程
例如:
建议:
Animal a = new Cat();
Animal a = new Dog();
//喂养的方法
public void feed(Animal a){
}
不建议:
Dong d = new Dog();
Cat c = new Cat();
单例模式(2种)
懒汉模式:
线程不安全 同步锁
延迟加载 调用时才会产生实例
饿汉模式:
线程安全 不具备延迟加载特性
当虚拟机加载时直接创建好对象
不管什么时候过来都直接返回创建好的对象
数据源以及分层开发
数据源
由于JDBC在访问数据库数据的时候会有效率低,安全性差,稳定性差的问题,所以java给出了连接池与数据源解决的方案.
-
连接池的工作原理
-
JNDI :
配置 tomcat数据源
<!-- 配置Tomcat的conf/context.xml -->
<!--想要获取tomcat集成的dbcp连接池 使用接口可以接收 -->
<!--
name:自行设置 唯一
auth:Container 固定 容器来托管数据源
type:javax.sql.DataSource 当服务器启动的时候 会自动帮你创建一个DataSource数据源的实现类
maxActive:最大活跃 (最大连接)
maxIdle:最大闲置(备胎)
maxWait:最大等待时间
username:数据库用户名
password:数据库密码
driverClassName:驱动名称
url:数据库地址
& :与符号&
useUnicode=true&characterEncoding=utf-8 防止项目编码和数据库编码不一致的情况 统一采用UTF-8
-->
<Resource name="jdbc/news" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000" username="root"
password="root" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/kgcnews?
useUnicode=true&characterEncoding=utf-8" />
引用 连接池代码 (获取连接对象)
public static void getConnection() throws Exception{
// 1.加载驱动
Class.forName(driver);
// 2.获取连接对象
//conn = DriverManager.getConnection(url,username,password);
// 通过连接池技术获取连接对象 每次关闭连接对象时并不会关闭掉 而是让连接对象返回到连接池
// 以下是重点
Context context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/news");
conn = dataSource.getConnection();
}
分层开发
层与层之间是依赖关系 dao -> service -> jsp
-
第一层:
dao: 数据访问层
-
第二层:
service: 业务逻辑层
-
第三层:
jsp: 访问层(展示与控制页面)
以后会分出来: controller: 控制层
以下是代码演示
- 登录
分析: 输入完用户名 密码 点击登录
1.js验证 接收form表单中的信息
// 字符编码
request.setCharacterEncoding("utf-8");
// 接收参数
String uname = request.getParameter("uname");
String upassword = request.getParameter("upassword");
// 去找userDao 帮我们去数据库查询
UserDao userDao = new UserDaoImpl();
// 查询用户名密码是否正确
User user = userDao.login(uname,upassword);
2.创建数据访问层 UserDao 的UserDaoImpl 实例 访问数据库查询是否有数据
public User login(String uname, String upassword) {
User user = null;
// 1.写sql语句
String sql = " select * from news_user where userName = ? and password = ? ";
// 2.执行
try {
select(sql,uname,upassword);
// 3.遍历结果集
while (rs.next()){
int id = rs.getInt("id");
String userName = rs.getString("userName");
String password = rs.getString("password");
String email = rs.getString("email");
int userType = rs.getInt("userType");
user = new User(id,userName,password,email,userType);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
closeAll();
} catch (Exception exception) {
exception.printStackTrace();
}
}
return user;
}
3.实现跳转
//3. 实现跳转
if (user == null){
// 提示用户名密码输入错误
request.setAttribute("msg","用户名或者密码错误!");
request.getRequestDispatcher(request.getContextPath()+"/index.jsp").forward(request,response);
}else{
// 重定向
session.setAttribute("user",user);
response.sendRedirect(request.getContextPath()+ "/pages/admin.jsp");
}
- 注销
1.js
$(".fr").click(function (){
location.href = "../controller/logout.jsp"
})
2.点击注销按钮