JavaEE(JavaWeb)笔记
JavaEE学什么
- 企业开发
- JavaWeb和JavaEE的区别,
- javaEE包含Javaweb
- JavaEE重点讲框架
- java实践
- 前端与后台的转换
预备
C/S模式
- 能充分发挥客户端PC的处理能力
- 安装和维护困难
B/S模式
- 不需要维护客户端,只需要维护服务器
- 不能发挥客户端pc的处理能力,服务器任务很重
请求与响应
应用服务器与web服务器
- Apache是web服务器,tomcat是应用服务器,包含apache。tomcat
- web服务器提供网页资源
HTTP
- 请求与响应的无状态协议,无状态前后两次没关联
URL和URI
- URL统一资源定位器,协议名、所在主机的DNS名、可选的端口号、资源路径名称
- URI是URL的抽象
动态网页与静态网页
- 静态网页只能由服务器的存在来改变
- 动态网页可以动态生成(代码),服务器接收学号和密码得到信息动态生成网页。
JavaEE产生背景
三层次开发,通过加一个中间层来减少服务器访问的压力
JavaEE中间件体系结构
中间件分为表层逻辑和业务逻辑层
四层
客户层
表示逻辑层
- 动态网页
- 用http应答表示到客户端浏览器
业务逻辑层
信息系统层
JavaEE是企业分布式应用开发的标准
- 规范了分布式组件开发的标准
- JavaEE规范了容器的标准
javaEE技术框架
- 组件技术、服务技术、通信技术、架构技术
- web Container
- JSP
- Servlet
- JDBC访问不同数据库的统一路径
javaEE基本的编程思想,组件容器
前端基础
- 之前已经学过,参考
AJAX异步刷新
- 传统的客户端要等服务器处理,网页刷新需要根据场合,输密码,因此提出异步刷新的技术
- 根据网页的更新需求,对需要更新的部分进行更新
Servlet编程
是什么?
- Applet回顾,网页浏览过程,遇到applet代码再次向服务器请求,服务器交给浏览器字节码,浏览器加载后运行动画
干什么?
服务器端的java应用程序,用来扩展服务器的功能,可以生成动态的web页面
都没用main函数
都不是用户调用,容器调用
有生存周期,包含init()和dstroy()
applet在客户端,servlet在服务器端
怎么用?
读数据
生成结果
怎么运行?
- init方法
- destroy方法
- service方法
工作流程
- 容器中有servlet程序,客户端请求容器,容器转发给
- 用户请求到容器,容器实例化到servlet,然后响应到容器,容器回复到客户端
- 类实例进入生命周期,可创建多个线程
编程接口
JavaServlet API
servlet类不支持html,HttpServlet继承了servlet方法,需要继承,然后定义用户的servlet
javax.servlet.http
request和response接口
Session接口
基本编程
- 创建javaWeb项目
- 新建servlet
- 重现doget和dopsot
- web应用程序环境
- charset 设置字符集
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// 扩展 HttpServlet 类
public class HelloWorld extends HttpServlet {
private String message;
public void init() throws ServletException
{
// 执行必需的初始化
message = "Hello World";
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// 设置响应内容类型
response.setContentType("text/html");
// 实际的逻辑是在这里
PrintWriter out = response.getWriter(); //输出到y
out.println("<h1>" + message + "</h1>");
}
public void destroy()
{
// 什么也不做
}
}
- http请求和响应结构
- getOutputStream()字节流
- 推荐使用注解来代替配置文件
- request.setCharacterEncoding(“GBK”);
高级编程
会话管理
- 客户端
- http,无状态
- 服务器
从某一个客户端发出的一系列请求构成一个会话(session),会话是用户私有的。
ServletContext,上下文 ?
结束会话的三种方式
- 关闭浏览器,服务器并不知道客户端关闭,所以其实会话其实并没有关闭,等待超时后关闭。
- 不能运行的原因,会话缓存被清空
- 调用HttpSession的invalide()方法
- 两次访问时间间隔大于Session定义的非活动时间间隔
- 关闭浏览器,服务器并不知道客户端关闭,所以其实会话其实并没有关闭,等待超时后关闭。
会话追踪技术
- Cookie
- URL重写
- 隐藏表单域
Cookie
服务器可以嵌入到客户端的一个数据,方便服务器获取
作业四,把登录表单的用户名和密码记住
服务器创建,客户端保存,对服务器来说很好
保存个人信息,喜好,个人资料
//创建
Cookie userCookie = new Cookie(“Name”,value);
//方法
get/setMaxAge(); //什么时候有效 >0 7*24*60*60s 保存7天,过了时间就失效了
// <0 -1 只在客户端的内存中 ,不写到硬盘,关闭浏览器失效
// =0 删除
set/getValue(); //Cookie中保存的内容,返回数组
setPath(); //指定可访问该Cookie的目录
- response.addCookie(); 将cookie带到客户端
- request.getCookies(); 读取Cookie
- Cookie的创建和使用
- 判断新用户、老用户
- 新用户
- 创建一个cookie,set,Save
- 老用户
- 找到cookie
doGet(){
Cookie cookue = null;
Cookie[] cookies = request.getCookies(); //拿到所有Cookie
boolean newCookie = false;
if(cookies! =null){
for(int i = 0; i<cookies.length;i++){
if(cookies[i].getName().equals(“SimpleServlet”)){ //名字是服务器给客户端取的
cookie = cookies[i];
}
}
}
if(cookie = null){
newCookie=true;
int maxAge = 1000; //有效期
cookie = new Cookie(“SimpleServlet”,”create by hyl”);
cookie.setPath(request.getContextPath());
cookie.setMaxAge(maxAge); //设置有效期
response.addCookie(cookie);//存储cookie到客户端
}
//显示信息
if(newCookie){
out.println(getcookie….);
}
}
//统计网页被访问的次数,每个客户访问的次数
void processRequest(request,response){
Cookie cookie= null;
Cookie[] cookies = request.getCookies();
if(cookies != null)
{
boolean flag = false;
for(int i = 0 ;(i<cookies.length)&&(!flag);i++)
{
if(cookies[i].getName().equals(“VisitTimes”)) { //切记不用==
String v = cookies[i].getValue();
int value = Integer[i].parseInt(v)+1;
cookies[i].setValue(Integer.toString(value));
cookies[i].setMaxAge(1000);
response.addCookie(cookies[i]);
flag = true;
cookie = cookies[i];
}
}
}
if(cookie == null)
{
cookie = new Cookie();
…
}
}
- Cookie可能会造成为隐私权的侵犯,用户可以关闭Cookie功能
- 应用Cookie计数器
URL重写
Post 和get提交
在URL地址后面怎加一个字符串来记录会话信息用 ?隔开的是多个参数。
URL/..?p1=”内容1”&p2=”内容2”
重写跟踪会话示例
//1.java
void processRquest(request,response){
response.setContentType(“text/html;charset=ntf-8”);
java.io.PrintWriter out =
String contexPath = request.getContextPath();
String encodedUrl = response.encodeURL(contextPAth+”/url?name = 张三”)
//如果客户端接收会话,则encode就是一个字符串的拼接
//如果客户端
上下文路径
}//2.java
public class 2 extends HttpServlet{
request.getParameter()
}response.encodeURL(java.lang.Stirng url)
会话跟踪
- 会话跟踪Httpsession不需要考虑客户端支不支持
- 获取会话对象
- 对会话对象进行读和写
- 手工终止会话,或者自动终止
public void Httpsession(HttpServletRequest request, HttpServletResponse response){
request.getSession();//不带参数
request.getSession();//带boolean参数,需要判断是否存在,然后不存在true创建一个会话,false返回null
session.getAttribute();
session.setAttribute();
}
//跟踪会话
static final String COUNTER_KEY =”Counter”;
HttpSession session = request.getParameter();
会话管理
- 每个会话用户私有
Servlet上下文
- 要比会话要大,包含了session
- 多客户端共享
- 上下文:服务器上的每个web应用都会有一个背景环境对象,上下文对象是一个不同资源间共享信息的场所
- 通过getServletContext()方法得到上下文对象
- set/getServletContext()
- 在上下文中的属性中保存web应用程序信息,全局共享
- 可以获取初始化参数
- 聊天室context,input放到context,show从context取数据
- 比较session和context的差别
- session和context都是数据存储的范围
- session是用户私有的,只对当前用户有效
- context是全局共享的,访问站点的用户都可以看到
Servlet间协作
requestdispatcher接口
多个servlet共同完成一个任务
导入javax.servlet.requestdispatcher接口
封装了访问同一个web应用内的另外一个资源的方法
- forward()
- include()
调用forward转向
//正确
RequestDispatcher dispatcher = request.getRequestDispatcher(“LoginSucess”);
//跳转
dispatcher.forward(request,response);
//包含
dispatcher.include(request,response);//不正确
页面已经显示了后面的页面,但是地址还是Main的地址,为什么?
- 浏览器B
- 表单request提交到Main
- 服务器Main、Success、Fail
- Main把请求转给了Success
- Success响应给浏览器response
- 对于浏览器来说,地址还是Main的地址,因为浏览器请求的是Main,这是服务器内部的转换,地址没有更新,请求指派是在服务器端进行的。
- 浏览器B
通过include方式,将原来登录的页面放到失败页面下面
Servlet Filter编程
Filter不是Servlet,它知识Servlet接收请求前的预处理器,
必须实现Filter接口
需要实现三个方法
- doFilter(ServletRuquest,ServletResponse)、init、destray
- 类似servlet
- 访问特定资源时的身份验证,禁止非法用户访问。
- 访问资源的记录跟踪
- 访问资源的转换
- Before
- chain.doFilter执行下一个个servlet,再回来
- After
- doFilter(ServletRuquest,ServletResponse)、init、destray
工作原理
过滤器可以拦截、修改、检查请求和响应
//before
代码
//doFilter
chain.doFilter(req,reps)
//after
代码客户端请求到filter1
filter1执行before、dofilter跳转到filter2
filter2执行before、dofiler跳转到sessionA
sessionA返回dofilter,执行after跳转回filter1
filter1执行after后返回到客户端
添加过滤器
用Filter接口的doFilter方法进行请求和响应的拦截。
开发步骤:详细
【实现Filter接口】
第一步:编写一个普通的java类HelloFilter,实现Filter接口,重写doFilter方法;
第二步:在doFilter方法中打印”请求被拦截了……”;【配置Filter】
第一步:在web.xml文件中配置Filter的类路径:
HelloFilter
<filter-class>com.heima.filter.HelloFilter</filter-class>
</filter>
第二步:配置HelloFilter拦截的Servlet的映射路径:
<filter-mapping>
<filter-name>HelloFilter</filter-name>
<url-pattern>/helloServlet</url-pattern>
</filter-mapping>
//原文链接:https://blog.csdn.net/u010835486/article/details/80730745编写HelloServlet,配置映射路径为/helloServle
启动tomcat,访问HelloServlet。
实现
package com.mazai.filter;
import javax.servlet.*;
import java.io.IOException;/**
* @author buguniao
* @version v1.0
* @date 2018/12/16 23:38
* @description TODO
**/
public class HelloFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println(“请求被拦截了…………..”);
}
@Override
public void destroy() {
}
}
————————————————
//原文链接:https://blog.csdn.net/u010835486/article/details/80730745
使用示例
if(request.getSession.getAttribute(“userSession”)==null)//如果为空就跳到错误页面
{
response.sendRedirect(“error/priv_error.jsp”);
reuturn;
}else{
chain.doFilter(request,response);//放行执行下一步页面
}分发条件
- request,只有当request直接来自客户,过滤器才生效
- forword,只有request被一个请求分发器使用forward方法转到另一个web组件时,过滤器才生效
- include,只有当request被一个请求分校其使用include方法转到一个web组件时,过滤器才生效
- error
listener监听器
- 监听事件
- 在察觉到客户请求事件,在事件发生前和发生后做处理
- 配置在web.xml
- 当某一个特定的事件发生的时候,将自动创建对应的listen呢人对象的实例并第哦啊用相应的接口方法进行处理。
- 监听对象,对应接口和事件
- servletcontext
- ServletContextListener、ServletContextEvent
- session
- requset
- servletcontext
- 监听Http会话的创建和销毁
- sessionCreated(HttpSessionEvent event)当会话创建时调用此方法
- sessionDestroyed(HttpSessionEvent event)当会会话销毁时,此方法进行处理
- getSession
- 实现ServletContextListener接口
- 上下文初始化时,写入历史文件,调用contextInitalized()
- 销毁上下文时,需要写入历史文件,调用contextDestroyed
JSP编程
- Java Server Pages
- jsp是一种动态页面技术标准
- jsp将servlet再一次封装,是基于java的服务器端的技术
- jsp可以在静态的html文件中嵌入Java代码
<%–注释–%>
JSP的脚本元素
注释
- JSP注释,注释内容不会被发送至浏览器甚至不会被编译
- HTML注释,通过浏览器查看网页源代码时可以看见注释内容
输出表达式 <%= 表达式 %>
jsp声明的变量
<%! int i = 0; %> 不带!是局部的变量
类、函数
JSP指令
include指令,jsp也米娜内嵌一个文件,这个文件可以是jsp文件或其他文件文本
<%@ include file = “relativeURL”%>
page指令
taglib指令
JSP动作组件
语法
描述
jsp:include
在页面被请求的时候引入一个文件。
jsp:useBean
寻找或者实例化一个JavaBean。
jsp:setProperty
设置JavaBean的属性。
jsp:getProperty
输出某个JavaBean的属性。
jsp:forward
把请求转到一个新的页面。
jsp:plugin
根据浏览器类型为Java插件生成OBJECT或EMBED标记。
jsp:element
定义动态XML元素
jsp:attribute
设置动态定义的XML元素属性。
jsp:body
设置动态定义的XML元素内容。
jsp:text
在JSP页面和文档中使用写入文本的模板
include
<jsp:include page=”文件名” flush = “true”/> 斜杠表示直接结束
前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。
合并为一个jsp文件,不能让变量有冲突
forward
后面的代码不执行,只能在同一个web应用内部,看到的是B页面的内容,地址是A的地址。
response.sendRedirect跳转的范围更广
注意,对于response.sendRedirect是与当前jsp对服务器的不同请求,不能共享参数
param
接收参数request.getparameter
JSP内置对象(隐式对象)
对象
描述
request
HttpServletRequest 接口的实例
response
HttpServletResponse 接口的实例
out
JspWriter类的实例,用于把结果输出至网页上
session
HttpSession类的实例
application
ServletContext类的实例,与应用上下文有关
config
ServletConfig类的实例
pageContext
PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page
类似于Java类中的this关键字
Exception
Exception类的对象,代表发生错误的JSP页面中对应的异常对象
reuqest对象的重要方法
- getCookies
- set/getAttribute,四个作用域都有这个方法
获取表单参数,getParameter传递的参数通常都是字符串
request.setCharacterEncoding(“GBK”);
<%long sum =0;
String s1 = request.getParameter(“sum”);%>
传递其他的参数可以考虑使用
一个jsp设置参数
<%request.setAttribute(“name”,”peter”);%>
<jsp:forward page = “Attribute_receive.jsp”>另一个jsp接收
<% String name = (String)request.getAttribute(“name”);%>
<%=name%>PageContext
Session对象,不能识别前后两次访问,实现会话跟踪
- 实现防止重复登录
Application对象
相当于上下文,就是context,服务器关闭停止运行,上下文就销毁
网页计数器
Cookies和Session做网页计数器
相同:都是同一个用户的访问次数
区别:Cookie可以保存很长时间,Session有效期
用Application做计数器,服务器关闭则计数清空
<%@ if(application.getAttribute("coounter") == null) application.setAttribute("counter","1"); else{ String times =null; times = application.getAttribute("counter"); int icount = 0; icount = ... } >- out对象,输出表达式
```jsp
<%= erpr %>
<% out.print() %>
表达式语言EL
EL,自动的在jsp中寻找对应的值,更简洁的输出
在页面上显示表达式的值,获取范围变量的值,即使用setAttribute方法保存到page、reuqest、
${sessionScope.user.name}或${user.name}
支持常见的所有数据类型,其中条件可以写成字母的形式
有十一个隐式对象
隐式对象
作用
pageContext
对应于JSP页面中的pageContext对象
pageScope
代表page域中用于保存属性的Map对象
requestScope
代表request域中用于保存属性的Map对象
sessionScope
代表session域中用于保存属性的Map对象
applicationScope
代表application域中用于保存属性的Map对象
param
表示一个保存了所有请求参数的Map对象
paramValues
表示一个保存了所有请求参数的Map对象,它对于某个请求参数, 返回的是一个string类型数组
header
表示一个保存了所有http请求头字段的Map对象
headerValues
表示一个保存了所有http请求头字段的Map对象,返回string类型数组
cookie
表示一个保存了所有cookie的Map对象
initParam
表示一个保存了所有web应用初始化参数的map对象
作用域
https://blog.csdn.net/w405722907/article/details/77530002
response.sendRedirect与jsp
- page 在当前页面中有效
- request 在当前请求中有效
- session 在当前会话中有效
- application 在所有应用程序中有效
汉字乱码问题
pageEncoding和charset的区别
<%@page contentType=”text/html” pageEncoding = “GBK”%>
<%@page contentType=”text/html charset = GBK”%>charset表示服务器传送给客户端的编码
JavaBean
定义
jsp的页面逻辑复杂、美化臃肿,需要javaBean分开
javaBean是一些可以移植、可重用,并可以组装到应用程序中的java类
就是一个java类
例子
定义一个不带任何参数的构造函数,属性私有化,属性应由一组public类型的读写方法getXxx()和setXxx()
对于Boolean变量对应的默认get方法,其名称是以is为前缀的。
与javaBean相关的jsp动作
jsp:useBean 声明一个具有一定生存范围及一个唯一id的javaBean的实例,jsp页面通过id来识别JavaBean,并可通过id.method类似的语句来操作javaBean。
- 定义对象
<jsp:useBean class = “Student” id = s1 scope = “application”/>
定义对象时,考虑是否存在一个同名的对象,如果存在就讲其值赋值给该对象,如果不存在则创建一个新的class所指定类型的对象。
- 返回一个已被创建对象的属性值
<jsp:getProperty name = “id” property = “pName”/>
<jsp:useBean id = “student1” scope =”page” class=“com.jsp.Student”/>
//不同的输出
<jsp:getProperty name = “student1” property = “name”/>
<%=student1.getName()%>
<%=student1.name%>
<% out.print(student1.name);%>
${student1.name}//不同的写入
<jsp:setProperty name = “student1” property = “name” value = “temp”/>
<%student1.setName(“zhang”);%>//赋值的对象为变量
<jsp:setProperty name = “student1” property = “name” param = “temp”/>
<jsp:setProperty name = “student1” property = “name”/><%student1.setName(“zhang”);%>
<%=student1.getName()%>- javaBean与页面
数据库编程
https://www.w3cschool.cn/jdbc/84pl1my8.html
JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。
Java DataBase Conection
一个数据库可以多种语言链接
数据库类型很多,使用JDBC可以不用关注数据库的类型
JDBC工作原理
数据库有关的接口
- 加载处理驱动建立连接 java.sql.DriverManager
- 对特定数据库的连接 java.sql.Connection
- 得到数据库集的数据表 java.sql.ResulSet
数据库连接
- 安装数据库
- 安装数据库驱动
搭建JDBC 开发环境
注册数据库驱动程序
如何选择正确的驱动程序?
使用JDBC URL作为自我表示的一种方法,用来标识正确的驱动程序
jdbc:子协议:数据库定位器
机器名:ip地址
jdbc:mysql://机器名/数据库名 端口默认为3306
jdbc:derby://机器名/数据库名 (glassfish内置的javaDB)
获取数据库连接
DriverManager.getConnection(“”)
示例代码
<%@page.contentType=”text/html;charset=gb2312”%>
<% java.sql.Connection conn;
java.lang.String strConn;
try{
Class.forName(“com.mysql.jdbc.Driver”).newInstance();
conn = java.sql.DriverMangaer.getConnection(“jdbc:mysql://机器名/数据库名”,”root”,””);
<% 数据库连接成功 %>
}catch(){
}
%>
创建/执行SQL语句
- ResultSet的接口常用方法
JDBC对数据库执行SQL
- 使用预编译的对象PreparedStatement进行带参数的数据库查询
- 可以带有一个或多个参数,在创建时可以用 (?)占位
MVC开发模式
- ORM
考试
单选10题 20分
- 上课的测试、servlet、listence、filter、jsp、JavaBean、jdbc、模式
程序填空题10题 20分
- 给一个程序,填变量、函数名、参数、类型
程序分析题15空 30分(
- 类似简答、原理流程
- 给一个程序、分析样子结果
分析题2小题 10分
编程题2题 20分
上课演示的程序、作业的、实验的内容
- 表单的接收提交
- 页面的跳转(servlet、jsp)
- Session对象的使用,会话跟踪
- 上下文对象的使用,聊天室
- Cookie程序
- Filter和listenner原理
编程题
JavaBean、自己写、调用
jdbc连数据库
