JSP初始
说明:以下内容如有侵权,请联系删除
经验分享
DAY02
回顾
1.软件的架构有哪两种B/S架构C/S架构
2.WEB资源分成哪两种静态资源动态资源
3. Tomcat项目发布的三种方式将资源文件放入webapps目录在server .xm1文件中配置【不推荐】配置独立的xm1文件
4. Idea配置Tomcat,创建web项目,部署web项目稍后会再次操作
5.浏览器开发工具查看HTTP协议请求和响应内容快捷键F12
6.请求内容请求首行:请求路径(携带参数)、请求方式、协议和版本请求头:都是一些key value的键值对【Referer User-Agent】请求体:就是你向服务器发起请求携带的数据【Get请求没有请求体、Post请求有请求体】
7.响应内容响应首行:响应状态码响应头:都是—些key value的键值对响应体:根据你的请求,服务器处理的—些结果数据
今日核心内容
1.能够使用浏览器开发工具查看HTTP协议响应内容
2.能够理解HTTP协议响应内容
3.能够使用idea编写servlet
4.能够使用注解开发servlet
5.能够说出servlet生命周期方法执行流程
6.能够说出servlet运行原理
第一章 Servlet入门
1.1 Servlet概述
Servlet它是一个接口,它的本质也是java程序,这个java程序是运行在服务器端的!【Javase阶段的程序都是从main方法开始执行的】
作用
★接收用户发起请求携带的数据
★处理请求(看需求)【程序员编写代码】
★将处理的结果响应到客户端浏览器
第二章 Servlet快速入门
目标:编写一个普通的java类,通过浏览器可以访问
2.1 代码编写
(1)创建web项目
(2)编写普通java类,实现servlet接口
编写servlet的步骤:
1.编写一个类去实现servlet接口
2.重写servlet接口中所有的抽象方法【在服务方法service中编写代码】
3.在web.xm1文件中配置(浏览器访问路径与servlet处理类的对应关系)
package com.itheima.web.servlet;import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;public class HelloServlet implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("HelloServlet~~~");}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}
(3)配置web.xml
配置servlet网络访问路径
<?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"><!--Servlet入门案例的配置--><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>com.itheima.web.servlet.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/HelloServlet</url-pattern></servlet-mapping>
</web-app>
(4)部署web项目
(5)启动测试
2.2 执行原理
第三章 Servlet相关API
3.1 声明周期相关
思想介绍
生命周期:指的是一个对象从生(创建)到死(销毁)的一个过程
本身我们使用面向对象的思想,应该先创建类的对象,然后拿着对象去调用方法来完成某些功能~====>>>现在的程序个在main方法中作为起点运行,而是放在Tomcat服务器中。====>>>类的对象由服务器容器Tomcat帮我们创建!
Tips:但凡与Servlet相关的所有类的对象的创建都是由服务器容器负责创建的!
/*下面3个方法就是与servlet生命周期相关的方法*///初始化方法,创建完对象后就会执行!@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}//服务方法:接收用户发起请求携带的数据、处理请求(看需求)【程序员编写代码】、将处理的结果响应到客户端浏览器@Overridepublic ServletConfig getServletConfig() {return null;}//销毁方法@Overridepublic void destroy() {}
代码演示
(1)LifeServlet
public class LifeServlet implements Servlet {@Overridepublic void destroy() {System.out.println("LifeServlet销毁了。。。");}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("LifeServlet正在处理用户请求。。。");}@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("LifeServlet正在进行初始化。。。");}public LifeServlet(){System.out.println("LifeServlet对象创建了。。。");}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic String getServletInfo() {return null;}}
(2)配置web.xml
<servlet><servlet-name>LifeServlet</servlet-name><servlet-class>com.itheima.web.servlet.LifeServlet</servlet-class></servlet><servlet-mapping><servlet-name>LifeServlet</servlet-name><url-pattern>/LifeServlet</url-pattern></servlet-mapping>
servlet生命周期:
默认情况,用户第一次发起请求,由服务器容器Tomcat创建Servlet实例对象,对象在整个Servlet生命周期中只会创建一次,然后紧接着调用init(Servletconfig config)方法来完成初始化操作,此方法在整个Servlet生命周期中只会执行1次!然后调用serivce(ServletRequest req, ServletResponse resp)服务方法来处理用户请求,这个方法在整个Servlet生命周期中会被执行多次(每访问一次Servlet就执行1次)。当关闭服务器的时候,会调用destroy(方法完成Servlet的销毁!
3.2 扩展:load-on-startup配置
3.3 拓展:ServletConfig
(1)EncodeServlet
public class EncodeServlet implements Servlet {@Overridepublic void init(ServletConfig config) throws ServletException {// 获得当前Servlet名称System.out.println(config.getServletName()); // EncodeServlet// 获得ServletContext对象 【重点】ServletContext context = config.getServletContext();System.out.println(context.getContextPath()); // /day02_code// 获得所有配置信息的初始化的名称Enumeration<String> parameterNames = config.getInitParameterNames();while (parameterNames.hasMoreElements()){System.out.println(parameterNames.nextElement());}// 获得配置的指定初始化名称对应的值System.out.println(config.getInitParameter("username")); // EncodeServlet}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic String getServletInfo() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {}@Overridepublic void destroy() {}
}
(2)配置web.xml
第四章 Servlet体系结构
实现Servlet除了实现Servlet接口方式以外,还有2种方式:
4.1 GenericServlet
4.2 HttpServlet[开发常用!]
4.3 Servlet体系结构
第五章 Servlet路径
5.1 url-pattern
作用:将一个请求网络地址和servlet类建立一个映射关系
Servlet映射多个url
url映射模式
5.2 相对/绝对路径
第六章 Servlet3.0
通过注解配置Servlet,简化web.xml配置Servlet复杂性,提高开发效率,几乎所有的框架都在使用注解
DAY03
回顾
1. servlet概述
Servlet它其实是一套规范(接口),我们需要实现这个接口里面的方法,就能完成一些功能(接收用户的请求数据<请求首行、请求头、请求体>、处理请求<根据用户的需求来决定>、响应处理的结果到客户端)【Servlet程序都是在服务器中运行!】2. xml配置servlet【掌握】
编写一个类去实现servlet接口(实现servlet接口中所有的抽象方法)【麻烦~】
编写一个类去继承GenericServlet抽象类(只需要重写抽象方法service(ServletRequestreq, ServletResponse resp))【它无法处理与Http协议相关的内容】
编写一个类去继承HttpServlet抽象类(根据用户的请求方式来重写对应的doXxx方法)。
HttpServlet是一个抽象类,但是里面没有抽象方法,java为什么这么设计呢?只要是一个抽象类,必须通过继承使用,java将HttpServlet设计成一个抽象类,说明不想让程序员自己去创建它的实例对象。因为HttpServlet的实例对象都必须是由服务器容器创建。在web.xml文件中去配置:在浏览器地址栏访问的路径与servlet处理类的对应关系!
<servlet><servlet-name>Servlet处理类的类名</servlet-name><servlet-class>servlet处理类的全限定类名</servlet-c1ass></servlet>
<servlet-mapping><servlet-name>Servlet处理类的类名</servlet-name><url-pattern>/abc</url-pattern>
</ servlet-mapping>3. servlet生命周期
默认情况,在用户第一次访问的时候,由服务器容器Tomcat负责创建Servlet实例对象!调用init(Servletconfig config)方法完成初始化(在整个servlet生命周期中只会执行一次! ),然后会调用服务法service(ServletRequest req,ServletResponse resp)来处理用户请求(在整个servlet生命周期中会执行多次!),当我们停止服务器,此时会调用destroy()方法完成销毁操作。通过配置1oad-on-stratup,让servlet在服务器启动的时候就创建~4. serv1et体系结构
servlet接口
Genericservlet抽象类
Httpservlet抽象类5. Servlet3.o
在Servlet处理类的上面加上下面的注解!
@WebServlet(urlPatterns=" /abc" , name="")
今日核心内容
1.Request概述2. reuqest获取请求消息内容请求行请求头请求参数(体)【重点】3. request其他功能请求转发域对象4.案例:用户登录
第一章 Request概述
用户通过浏览器访问服务器时,Tomcat将HTTP请求中所有的信息都封装在Request对象中
作用:开发人员可以通过request对象方法,来获取浏览器发送的所有信息
所有请求相关的数据都封装在这个对象中,我们可以通过这个对象相关的方法来获得对应的数据!
第二章 Request获取Http请求信息
2.1 获取请求首行信息
例如:【Http请求协议:请求首行的内容】GET /day09_request/requestDemo1 HTTP/1.1相关API:1.获取请求方式 GET【掌握】String getMethod()2.获取项目虚拟路径(项目名)/day-9_request【掌握】String getContextPath()3.获取URI/day09_request/requestDemo1统一资源标识符(范围广)共和国String getRequestURI()4.获取URL http://localhost:8080/day09_request/requestDemo1统一资源定位符(确定某一个地址)中华人名共和国StringBuffer getRequestURL()5.获取协议和版本号 HTTP/1.1String getProtocol()6.获取客户端IPString getRemoteAddr()
/*HttpServletRequest对象 与请求首行相关的方法!*/
@WebServlet(name = "AServlet", urlPatterns = "/AServlet")
public class AServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {// 获得用户的请求方式String method = request.getMethod();System.out.println("用户请求方式:" + method);// 获得项目的虚拟路径(项目名称的路径)String contextPath = request.getContextPath();System.out.println("项目虚拟路径是:" + contextPath);// 获得uri 【端口号之后,参数之前】String uri = request.getRequestURI();System.out.println("uri: " + uri);// 获得url 【一整个长串,也不包含参数】StringBuffer url = request.getRequestURL();System.out.println("url: " + url);// 获得客户端ip地址String addr = request.getRemoteAddr();System.out.println("发起请求客户端ip地址是:" + addr);// 协议版本String protocol = request.getProtocol();System.out.println("协议:" + protocol);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
2.2 获取请求头信息
案例:视频防盗链
案例:浏览器兼容性
2.3 获取请求参数(体)
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><title>form</title></head><body><h3>get方式:</h3><form action="/day03_code/EServlet" method="get">用户:<input type="text" name="username"> <br>密码:<input type="password" name="password"> <br>爱好:<input type="checkbox" name="hobby" value="somke"/>抽烟<input type="checkbox" name="hobby" value="drink"/>喝酒<input type="checkbox" name="hobby" value="perm"/>烫头<input type="submit" value="get提交..."></form><h3>post方式:</h3><form action="/day03_code/EServlet" method="post">用户:<input type="text" name="username"> <br>密码:<input type="password" name="password"> <br>爱好:<input type="checkbox" name="hobby" value="somke"/>抽烟<input type="checkbox" name="hobby" value="drink"/>喝酒<input type="checkbox" name="hobby" value="perm"/>烫头<input type="submit" value="post提交..."></form></body>
</html>
/*HttpServletRequest与请求参数相关的方法*/
@WebServlet(name = "EServlet", urlPatterns = "/EServlet")
public class EServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {// 获得请求参数:用户名String username = request.getParameter("username");// 参数是页面表单name属性的值System.out.println("用户在表单中输入的用户名是:" + username);// 获得请求参数:密码String password = request.getParameter("password");System.out.println("用户在表单中输入的密码是:"+password);// 获得请求参数:爱好 【getParameter方法适合一个参数一个值的情形!】/*String hobby = request.getParameter("hobby");System.out.println("爱好:" + hobby); // 丢失后面的数据*/// 一个参数名对应多个参数值: getParameterValues方法!String[] hobbies = request.getParameterValues("hobby");for (String hobby : hobbies) {System.out.println("爱好:" + hobby);}System.out.println("===========================================");// 一次性获得提交请求携带的所有参数数据Map<String, String[]> map = request.getParameterMap();for(String key:map.keySet()){String[] values = map.get(key);for (String value : values) {System.out.println("key:" + key +"======>>>" + "value:" + value);}}}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
/*HttpServletRequest与请求参数相关的方法*/
@WebServlet(name = "EServlet", urlPatterns = "/EServlet")
public class EServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {// 告诉服务器使用指定的码表来解码 【这行代码需要放在方法的第一行】request.setCharacterEncoding("utf-8"); // 此方法只对请求体有效!// 获得请求参数:用户名String username = request.getParameter("username");// 参数是页面表单name属性的值System.out.println("用户在表单中输入的用户名是:" + username);// 获得请求参数:密码String password = request.getParameter("password");System.out.println("用户在表单中输入的密码是:"+password);// 获得请求参数:爱好 【getParameter方法适合一个参数一个值的情形!】/*String hobby = request.getParameter("hobby");System.out.println("爱好:" + hobby); // 丢失后面的数据*/// 一个参数名对应多个参数值: getParameterValues方法!String[] hobbies = request.getParameterValues("hobby");for (String hobby : hobbies) {System.out.println("爱好:" + hobby);}System.out.println("===========================================");// 一次性获得提交请求携带的所有参数数据Map<String, String[]> map = request.getParameterMap();for(String key:map.keySet()){String[] values = map.get(key);for (String value : values) {System.out.println("key:" + key +"======>>>" + "value:" + value);}}}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
2.4 BeanUtils
(1)JavaBean
/*普通Java类:用于封装页面表单提交的数据Serializable:标记接口(里面什么也没有,保证JavaBean能够顺利的完成序列化)*/
public class User implements Serializable {/*类中的属性来自于页面表单的属性!【建议属性与页面表单的name属性值保持一致!】*/private String username;// 用户名private String password; // 密码private String[] hobby; // 爱好public User() {}public User(String username, String password, String[] hobby) {this.username = username;this.password = password;this.hobby = hobby;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String[] getHobby() {return hobby;}public void setHobby(String[] hobby) {this.hobby = hobby;}
}
(2)页面表单
(3)FServlet
/*BeanUtils工具类的使用*/
@WebServlet(name = "FServlet", urlPatterns = "/FServlet")
public class FServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");// 一次性获得所有的请求参数数据Map<String, String[]> map = request.getParameterMap();// 创建对象 【将页面表单用户输入的数据封装到这个user对象中】User user = new User();// 使用BeanUtils工具类将map中的数据封装到user对象中去try {BeanUtils.populate(user,map);} catch (Exception e) {e.printStackTrace();}// 测试System.out.println(user.getUsername());System.out.println(user.getPassword());System.out.println(Arrays.toString(user.getHobby()));}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
第三章 Request其它功能
3.1 请求转发
3.2 域对象(共享数据)
第四章 案例:用户登录
代码实现
(1)编写login.html
(2)User实体类
说明:直接使用BeanUtils知识点的User类即可
(3)LoginServlet
/*用户登录Servlet*/
@WebServlet(name = "LoginServlet", urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("utf-8");// 一次性获得用户在页面表单输入的用户名和密码数据Map<String, String[]> map = request.getParameterMap();// 创建JavaBean的示例对象User user = new User();// 使用BeanUtils封装数据到user对象try {BeanUtils.populate(user, map);} catch (Exception e) {e.printStackTrace();}// 只有用户名为jack,密码为123的用户才能登录成功~ 【作业:文件存储一些事先准备好的数据(用户名和密码)】if("jack".equals(user.getUsername()) && "123".equals(user.getPassword())){// 登录成功~ 将提示信息保存到request域中request.setAttribute("msg","<h3 style='color:green'>恭喜您,登录成功~</h3>");// 转发到登录成功的Servletrequest.getRequestDispatcher("SuccessServlet").forward(request,response);}else{// 登陆失败~将提示信息保存到request域中request.setAttribute("msg","<h3 style='color:red'>用户名或密码错误~</h3>");// 转发到登录成功的Servletrequest.getRequestDispatcher("FailServlet").forward(request,response);}}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
(4)SuccessServlet
(5)FailServlet
附录
Servlet模板设置
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
@javax.servlet.annotation.WebServlet("/${Class_Name}")
public class ${Class_Name} extends javax.servlet.http.HttpServlet {protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {this.doPost(request,response);}protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {}}
DAY04
回顾
1. request作用
HttpServletRequest子接口(具备处理与Http请求协议相关的能力),主要用于处理所有与请求相关的内容(请求首行、请求头、请求参数<体>),作为域对象(存放数据),请求转发(服务器内部资源的一个跳转)。2. request获取Http请求信息请求行string getMethod(;//获得用户的请求方式string getRemoteAddr() ;//获得客户端的ip地址请求头string getHeader(string headerName);//获得指定名称请求头的值Referer :进入当前资源的上一个历史地址―【防盗链】User-Agent:客户端浏览器与操作系统的版本信息[浏览器兼容问题]请求参数(体)string getParameter(string name);//获得指定参数名称的值【一个参数名称对应一个参数值】string[] getParametervalues(String name);//获得一个参数名称对应多个参数值Map<String,string[]> getPar ameterMap();/一次性获得所有的参数和值,构成一个map集合3.请求转发服务器内部资源的一个跳转~一次请求,浏览器地址栏不会发生改变~request.getRequestDispatcher("服务器内部资源的一个路径").forward(request , response);4.域对象(共享数据)何时创建?当用户发起请求的时候何时销毁?当得到服务器响应的时候作用范围?一次请求~【请求转发是一次请求,超过一次请求,那么之前向r equest域中存放的数据就获取不到。】5.案例:用户登录【书写3次~】
从登录页面(表单),点击登录按钮,指向服务器端的Loginservlet在LoginServlet中,获得用户在表单中输入的用户名和密码数据,借助BeanUtils封装到User对象中去,用指定的用户名与用户输入的用户名密码数据进行匹配,匹配成功,说明登录成功,将提示信息保存到request域中,转发到一个SuccessServlet,获取request域中的数据,显示到浏览器;匹配失败,说明登录失败,将提示信息保存到r equest域中,转发到一个Fai1servlet,获取request域中的数据,显示到浏览器。
今日目标
1. servletcontext:应用上下文对象
2. response【重点】
3.综合案例
第一章 ServletContext
1.1 概述
web容器(tomcat)在启动时,它会为每个web项目创建一个对应的ServletContext对象
它代表:当前web项目
1.2 域对象(共享数据)
1.3 获取资源在服务器的真实地址
1.4 获取全局的配置参数
1.5 获取文件MIME类型
1.6 案例:统计网站的访问次数
/*统计访问网站次数*/
@WebServlet(urlPatterns = "/EServlet")
public class EServlet extends HttpServlet {// 这个初始化方法,在执行init(ServletConfig config)的时候,会调用无参的init()方法@Overridepublic void init() throws ServletException {// 定义一个变量充当计数器int count = 0;// 将计数器放入ServletContext域中getServletContext().setAttribute("count", count);}@Overridepublic void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获得ServletContextServletContext context = getServletContext();// 从ServletContext域中获取计数器变量int count = (int) context.getAttribute("count");// 将访问的次数输出到控制台System.out.println("本网站已被访问:" + ++count + "次!");// 将更新后的计数器的值重新放入ServletContext域中context.setAttribute("count",count);}@Overridepublic void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 处理POST请求中文乱码req.setCharacterEncoding("utf-8");// 处理响应中文乱码[目前照抄]resp.setContentType("text/html;charset=utf-8");// 调用doGetdoGet(req, resp);}
}
第二章 Response
2.1 概述
2.2 设置Http响应消息
2.3 响应重定向
2.4 响应定时刷新
2.5 响应中文
第三章 综合案例
3.1 点击切换验证码(js实现)
验证码制作Servlet工具类
/*跟我一起了解一下验证码的制作代码....*/
@WebServlet(urlPatterns = "/CheckcodeServlet")
public class CheckcodeServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 创建画布int width = 120;int height = 40;BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获得画笔Graphics g = bufferedImage.getGraphics();// 填充背景颜色g.setColor(Color.white);g.fillRect(0, 0, width, height);// 绘制边框g.setColor(Color.red);g.drawRect(0, 0, width - 1, height - 1);// 生成随机字符// 准备数据String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";// 准备随机对象Random r = new Random();// 声明一个变量 保存验证码String code = "";// 书写4个随机字符for (int i = 0; i < 4; i++) {// 设置字体g.setFont(new Font("宋体", Font.BOLD, 28));// 设置随机颜色g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));String str = data.charAt(r.nextInt(data.length())) + "";g.drawString(str, 10 + i * 28, 30);// 将新的字符 保存到验证码中code = code + str;}// 绘制干扰线for (int i = 0; i < 6; i++) {// 设置随机颜色g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));}// 将验证码 打印到控制台System.out.println(code);// 将验证码放到session中request.getSession().setAttribute("code_session", code);// 将画布显示在浏览器中ImageIO.write(bufferedImage, "jpg", response.getOutputStream());}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}
3.1 点击切换验证码(自己使用js实现)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><form action="/day04_code/LoginServlet">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br>验证码:<img src="/day04_code/CheckcodeServlet" onclick="changeImage()"><br><input type="submit" value="登录"></form><script>function changeImage() {let imgs=document.querySelector("img")imgs.src="/day04_code/CheckcodeServlet?time="+new Date().getTime()}</script></body>
</html>
3.1 点击切换验证码(自己使用jQuery实现)
3.1 点击切换验证码(自己使用jQuery实现)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title><script src="../js/jquery-3.4.1.min.js"></script></head><body><form action="/day04_code/LoginServlet">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br>验证码:<img src="/day04_code/CheckcodeServlet"><br><input type="submit" value="登录"></form><script>$("img").click(function () {//this是js对象,必须转化成jQuery对象$(this).attr("src","/day04_code/CheckcodeServlet?time="+new Date().getTime())})</script></body>
</html>
3.2 文件下载
3.2.1 使用链接下载文件
3.2.2 使用Servlet下载文件【推荐】
(1)download.html
(2)DownLoadServlet
@WebServlet(name = "DownLoadServlet", urlPatterns = "/DownLoadServlet")
public class DownLoadServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("utf-8");// 获得filename参数的值 (资源文件名称)String filename = request.getParameter("filename");// 设置2个头response.setHeader("Content-Disposition","attachment;filename="+filename);// 此头可以省略String mimeType = getServletContext().getMimeType(filename);response.setHeader("Content-Type",mimeType);// 设置2个流String realPath = getServletContext().getRealPath("/download/" + filename);//System.out.println(realPath);FileInputStream is = new FileInputStream(realPath);ServletOutputStream os = response.getOutputStream();// 流拷贝IOUtils.copy(is,os);// 释放资源os.close();is.close();}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
问题:点击中文文件名称(禽兽.jpg)下载,发现下载框,文件名显示不正常,但是数据是没有问题的
(3)中文乱码
DAY05
回顾
1. ServletContext对象--代表的是整个WEB应用(与项目共存)生命周期:在服务器启动的时候对象创建当服务器停止或者项目移除,对象销毁作为域对象相关的方法:【必须先设置值才能获取到值】设置值: void setAttribute(string name,object obj);获取值:object getAttribute(string name);删除值: void removeAttribute(string name);2. Servletcontext功能方法获得资源文件的真实路径: string getRealPath(String path);//参数是一个虚拟的路径书写虚拟路径:/资源文件名称的路径︰【/代表的是项目,后面的路径就是相对于项目的路径,最终得到真实地址】可以获得项目路径: String getContextPath();//得到的结果是:/day04_codea获得指定资源文件的Mime类型: string getMimeType(String filename);3. Response对象所有与响应相关的内容都封装到这个对象中去了~Http响应协议:首行:状态码(200 302 304 404405 500)setstatus (int sc);头: Refr esh(定时刷新)、Location(结合302状态码完成重定向)setHeader (string name , string value);体:响应到客户端浏览器的内容getwriter ().write(;/l/字符流【纯文本数据】getoutputStream().write();//字节流【图片、视频、音频(文件下载)】重定向:特点:它是两次请求浏览器地址栏会发生改变重定向的资源位置可以是服务器内部,也可以是服务器外部无法获取request域中的数据4. Response响应中文一行代码搞定一切∶既规定了服务器响应中文数据的编码的码表(utf-8),又告诉了浏览器使用该码表来解析数据(utf-8)response.setContentType("text/htm1; charset=utf-8");//放在响应数据之前~
5.综合案例点击切换验证码回忆之前的javascript的知识(页面加载函数,事件绑定,元素数据获取,属性操作,Date对象)文件下载核心:2个头,2个流2个头:Content-Type:文件的Mime类型Content-Disposition:告诉浏览器无论如何都要弹出下载框2个流:文件通过2个流来传递数据通过服务器指定文件的真实路径来创建一个输入流通过response对象获得输出流getoutputstream
第一章 会话概述
1.1 什么是会话?
1.2 会话技术
第二章 Cookie
2.1 概述
2.2 快速入门
/*Cookie操作获取Cookie的数据*/
@WebServlet(name = "BServlet", urlPatterns = "/BServlet")
public class BServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("utf-8");// 获得所有的CookieCookie[] cookies = request.getCookies();// 非空判断if(cookies!=null){// 遍历for (Cookie cookie : cookies) {// 判断(拿指定名称的cookie)if("username".equals(cookie.getName())){// 获取该cookie的值System.out.println(cookie.getValue());}}}}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
2.3 工作原理
2.4 Cookie细节
服务器发送多个Cookie?
/*服务器端向客户端响应多个Cookie*/
@WebServlet(name = "CServlet", urlPatterns = "/CServlet")
public class CServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("utf-8");// 创建Cookie对象,并设置数据Cookie cookie1 = new Cookie("username","jack");// 创建Cookie对象,并设置数据Cookie cookie2 = new Cookie("password","123");// 响应cookieresponse.addCookie(cookie1);response.addCookie(cookie2);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
Cookie在浏览器保存时间?
/*Cookie的生命周期:*/
@WebServlet(name = "DServlet", urlPatterns = "/DServlet")
public class DServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("utf-8");// 创建Cookie对象并设置值Cookie cookie = new Cookie("username","jack");// 设置Cookie的存活时间cookie.setMaxAge(60*60*24*7); // 一周// 响应cookieresponse.addCookie(cookie);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);}}
Cookie是否可以存储中文?
Cookie共享数据的范围?
此时,测试,我们发现在FServlet中设置的cookie数据,去访问Gservlet,并没有携带带服务器端
2.5 Cookie特点
第三章 综合案例
3.1 用户上次访问记录
需求
访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您的到来。
如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:XXXX。
需求分析
代码实现
LastVisitServlet
@WebServlet(name = "LastVisitServlet", urlPatterns = "/LastVisitServlet")
public class LastVisitServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");// 获得指定名称的Cookie (last_time)Cookie[] cookies = request.getCookies();Cookie last_time = CookieUtils.findCookieByName(cookies, "last_time");// 判断if(last_time!=null){// 说明不是第一次String value = last_time.getValue();// 显示在浏览器response.getWriter().write("<h3 style='color:red'>客官,您上一次访问本店的时间是:"+value+"</h3>");}else{// 说明是第一次response.getWriter().write("<h3 style='color:green'>客官,你是第一次光临本店,欢迎光临~</h3>");}// 不管是不是第一次,我们都需要更新当前时间到cookie中去SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日-HH:mm:ss");String date = simpleDateFormat.format(new Date());Cookie cookie = new Cookie("last_time",date);// 设置cookiecookie.setMaxAge(60*60*24*365);// 响应response.addCookie(cookie);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
3.2 jsp初体验
3.3 商品浏览记录【第一遍根据画图找这抄】
需求
做一个商品页面,当我们访问后,在页面上点击查看商品浏览记录后,可以查看到以前浏览过的商品信息
需求分析
代码实现
(1)goods.html
(2)GoodslnfoServlet
/*商品浏览记录Servlet*/
@WebServlet(name = "GoodsInfoServlet", urlPatterns = "/GoodsInfoServlet")
public class GoodsInfoServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");// 1.获得请求参数name的值String product = request.getParameter("name");// 2.展示当前浏览的商品信息response.getWriter().write("您当前正在浏览的商品为:" + product);// 3.获得指定名称的cookieCookie cookie = CookieUtils.findCookieByName(request.getCookies(), "goods_name");// 4.判断if(cookie ==null){// 5.之前没有浏览记录,将当前正在浏览的商品添加到cookiecookie = new Cookie("goods_name",product);}else{// 6.之前有浏览记录,取出 【浏览记录可能有很多的】 统一格式: 小米10-华为p40String value = cookie.getValue();// 7.判断当前商品是否在cookie中String[] split = value.split("-");List<String> list = Arrays.asList(split);if(!list.contains(product)) {// 8.不包含,追加,不做其他操作value = value + "-" + product; // 小米10-华为P40}// 9. 将value,重置到cookie中cookie = new Cookie("goods_name",value);}// 10.设置cookie的存活时间cookie.setMaxAge(60*60*24*365);// 11.响应response.addCookie(cookie);// 12.制作链接response.getWriter().write("<br><a href='/day05_code/html/goods.html'>继续浏览</a>");response.getWriter().write("<br><a href='/day05_code/jsp/history.jsp'>浏览记录</a>");}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
(3)history.jsp
<%@ page import="com.itheima.web.servlet.utils.CookieUtils" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>浏览记录页面</title></head><body><%// 编写Java代码// 获得指定名称的cookieCookie cookie = CookieUtils.findCookieByName(request.getCookies(), "goods_name");// 非空判断if(cookie == null){// 没有记录out.write("暂无浏览记录...");}else{// 有记录,遍历显示out.write("浏览记录如下:<br>");String value = cookie.getValue(); // 格式:小米10-华为P40// 遍历for (String product : value.split("-")) {// 显示out.write("<span sytle='color:red'>"+product+"</span><br>");}}%></body>
</html>
DAY06
回顾
1.会话技术
http是无状态协议,多次请求之间相互独立,不能共享数据会话技术为了解决多次请求之间,共享数据问题
cookie将数据存储到客户端【当用户发起请求,在服务器端创建cookie,然后将Cookie响应到客户端浏览器保存】2. cookie快速入门
设置cookie 【cookie只能存放字符串数据】//创建Cookie对象并设置数据Cookie cookie = new cookie(string name , string value);//将Cookie响应到客户端浏览器response.addcookie(cookie);
接收cookie【用户发起第二次请求,到达服务器端,服务器去获取之前存储在客户端的数据】//获得所有的CookieCookie[]cookies = request.getCookies();/从这些Cookie中获取指定名称的cookiefor (Cookie cookie:cookies){//判断if("goods_name ".equals(cookie.getName()){//获得指定名称cookie的值string value = cookie.getvalue();}}3. cookie使用细节
服务器一次可以发送多个cookietomcat8及以上版本支持中文,但不支持特殊符号(空格、逗号、分号、加号)
URLEncoder编码
URLDecoder解码cookie.setPath(String path);设置cookie的携带路径
一旦设置cookie的路径,以后想要访问服务器将cookie成功携带过去,那么访问的路径必须包含cookie设置
的路径cookie.setMaxAge(int second);// cookie默认是一个会话级别【关闭浏览器,cookie就没了】
正数:持久的cookie
负数:会话级别的cookie
零:直接杀死cookie[自动登录(复选框),将cookie杀死,或者不携带cookie]4. cookie特点
数据存储在客户端,可以存中文,单个大小不能超过4KB,数量不能超过20个,浏览器存储所有服务器的cookie总个数不超过300个,数据不太安全..5.综合案例
上次访问时间--> jsp<%放入Servlet中的代码%>
商品浏览记录
第一章 Session
1.1 概述
1.2 快速入门
1.3 工作原理
1.4 Session细节
客户端关闭,服务器不关闭
@WebServlet(name = "AServlet", urlPatterns = "/AServlet")
public class AServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");// 获得HttpSession对象HttpSession session = request.getSession();System.out.println(session);// 向session域中设置值session.setAttribute("msg","session域中的数据");// 不用响应(session是存在服务器端的)///////////////////////////////////////////////////// 手动修改cookie,关闭保留JSESSIONString id = session.getId();Cookie cookie = new Cookie("JSESSIONID",id);// 设置路径cookie.setPath("/day06_code");// 设置存活时间cookie.setMaxAge(60*60*24);// 响应response.addCookie(cookie);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
客户端不关闭,服务器关闭
生命周期
URL重写
1.5 Session特点
第二章 三大域对象总结
request、session、ServletContext
2.1 API
2.2 生命周期
ServletContext域对象
HttpSession域对象
HttpServletRequest域对象
第三章 综合案例
3.1 用户登陆(验证码)
需求
用户访问带有验证码的登录页面,输入用户名,密码以及验证码实现登录功能。
需求分析
代码实现
(1)创建web项目
(2)导入验证码Servlet
(3)login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Insert title here</title><%--引入jQuery核心js文件--%><script src="../js/jquery-1.11.0.js"></script><script>/*window.onload = function () {// alert("xxx");// 为图片绑定一个鼠标单击事件document.getElementsByTagName("img")[0].onclick = function () {// alert("xxx");this.src="/day04_code/CheckcodeServlet?time="+ new Date().getTime();}}*/// 页面加载函数$(function () {// 为图片标签绑定一个鼠标单击事件$("img").click(function () {$(this).prop("src","/day06_code/CheckcodeServlet?time="+ new Date().getTime());});});</script></head><body><form action="/day06_code/LoginServlet">用户名:<input type="text" name="username" /><br/>密码:<input type="password" name="password" /><br/>验证码:<input type="text" name="code"><img src="/day06_code/CheckcodeServlet" /><br><input type="submit" value="登录"/></form></body>
</html>
(4)LoginServlet
/**** 用户登录的Servlet**/
@WebServlet(name = "LoginServlet", urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");//////////////////////////////// 验证码校验成功才行!// 1.获得用户在表单中输入的验证码String code = request.getParameter("code");// 2.获得服务器生成的验证码数据String verifyCode = (String) request.getSession().getAttribute("code_session");// 3.校验if(!verifyCode.equalsIgnoreCase(code)){// 校验失败,将错误的提示信息保存到request域request.setAttribute("vcodemsg","验证码校验失败");// 转发request.getRequestDispatcher("/jsp/login.jsp").forward(request,response);// 不让后面的代码执行return;}/////////////////////////////// 程序能执行到这里,说明验证码校验成功,要校验用户名和密码数据了// 4. 获得用户名和密码数据String username = request.getParameter("username");String password = request.getParameter("password");// 5. 判断if(!("jack".equals(username) && "123".equals(password))){// 用户名或密码错误request.setAttribute("umsg","用户名或密码错误");// 转发request.getRequestDispatcher("/jsp/login.jsp").forward(request,response);// 不让后面的代码执行return;}/////////////////////////////// 程序能执行到这里,说明验证码校验成功,用户名和密码也校验成功了// 6. 将用户信息(用户名)保存到session域中request.getSession().setAttribute("username",username);// 7. 重定向到 success.jspresponse.sendRedirect("/day06_code/jsp/success.jsp");}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
(5)login.jsp
(6)success.jsp
使用ajax实现用户登录(ajax实现的主要是验证码内容)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Insert title here</title><%--引入jQuery核心js文件--%><script src="js/jquery-1.11.0.js"></script></head><body><form action="/day06_code/LoginServlet">用户名:<input type="text" name="username" /><br/>密码:<input type="password" name="password" /><br/>验证码:<input type="text" id="check"><img src="/day06_code/CheckcodeServlet" /><span style="color: red"></span><br><input type="hidden" name="method" value="login"><input type="submit" value="登录"/><script>$("img").click(function () {$(this).prop("src","/day06_code/CheckcodeServlet?time="+ new Date().getTime());})$("#check").blur(function () {$("span").html("")let code=$(this).val();$.ajax({url:"/day06_code/LoginServlet",data:{"code":code,"method":"checkCode"},type:"post",dataType:"text",success:function (data) {$("span").html(data)}})})</script></form></body>
</html>
@WebServlet(name = "LoginServlet", urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");String method = request.getParameter("method");if ("checkCode".equals(method)) {checkCode(request,response);}else if("login".equals(method)){login(request,response);}}protected void checkCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String code_session = (String)request.getSession().getAttribute("code_session");String code = request.getParameter("code");if (!code_session.equals(code)) {response.getWriter().write("验证码错误");}}protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}}
3.2 商品购物车
需求
有一个商品页面,可以点击超链接将商品添加到购物车,还有一个超链接点击它的时候可以查看购物车中商品信息
需求分析
代码实现
(1)goods.jsp
(2)AddCartServlet
/**商品添加到购物车*/
@WebServlet(name = "AddCartServlet", urlPatterns = "/AddCartServlet")
public class AddCartServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");// 1. 获取请求参数name的值String product = request.getParameter("name");// 2. 响应结果到浏览器response.getWriter().write(product+", 商品已成功加入购物车!<br><br>");// 3. 从session中获得购物车Map<String,Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");// 4. 判断购物车是否为空if(cart ==null){// 创建购车对象cart = new HashMap<>();}// 5. 判断购物车中是否有当前添加的商品if(cart.containsKey(product)){// 6. 购物车中存在当前添加的商品,不用添加商品到购物车,直接将数量+1Integer oldCount = cart.get(product);cart.put(product,oldCount+1);}else{// 7. 购物车中不存在当前添加的商品,添加到购物车cart.put(product,1);}// 8.重新将购物车添加到sessionrequest.getSession().setAttribute("cart",cart);// 9.记录浏览超链接response.getWriter().write("<a href='/day06_code/jsp/goods.jsp'>继续浏览</a><br><br>");// 10.查看购物超链接response.getWriter().write("<a href='/day06_code/jsp/cart.jsp'>查看购物车</a>");}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
(3)cart.jsp
<%@ page import="java.util.Map" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>cart</title></head><body><h3>购物车页面</h3><table border="1" width="200px" align="center"><tr><th>商品</th><th>数量</th></tr><%// 1. 从session域中获得购物车Map<String ,Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");// 2. 判断是否为空if(cart == null){// 说明没有out.write("购物车内部没有任何商品<br><br>");}else{// 3. 遍历for(String key:cart.keySet()){out.write("<tr><td>"+key+"</td><td>"+cart.get(key)+"</td></tr>");}}%></table></body>
</html>
DAY07
回顾
1. session作用
在一次会话中,多次请求间,共享数据,在服务器中存储
谷歌:向服务器发起请求【只要没关闭浏览器,那么此时所有的操作都在一次会话中(都是同一个Session对象)】
IE:向服务器发起请求【只要没关闭浏览器,那么所有的操作都在一次会话中,与上面的不是同一个会话】
Httpsession session = request.getsession();2. session快速入门
获得session对象--Httpsession session = request.getsession();
存数据--session.setAttribute(string name , 0bject value);
取数据--object object = session.getAttribute(string name);
工作原理--依赖cookie技术3. session使用细节
(1)浏览器关闭,服务器不关闭,二次获取session数据是否一致?
Session对象以及里面的数据依旧保留在服务器端,只不过你关闭浏览器,cookie没了,里面保存的
JSESSIONID丢失了,下次访问的时候,获得session就是一个新的!【默认情况是拿不到数据】
其实,我们可以让第二次请求里面依旧获得第一次请求向session中设置的值~【手动维护JESESSIONID】(2)浏览器不关闭,服务器关闭,二次获取session数据是否一致?
正常关闭: session对象以及里面的数据会进行序列化到磁盘,下次启动服务器将其加载到内存。【可以的】
正常关闭服务器后,会在磁盘的一个位置看到一个session持久化的文件,再次启动这个文件会消失
非正常关闭,session对象会销毁!(3)生命周期
创建?request.getsessionO;【不够精确】浏览器携带jsessionid与服务器不匹配时创建
销毁?非正常关闭为活跃30分钟自杀
作用范围?在一次会话中,多次请求间4.三大域对象
servletContex
tHttpsession
HttpservletRequest
第一章 JSP
1.1 概述
在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变。为了弥补Servlet的缺陷,SUN公司在Servlet的基础上推出了JSP (Java Server Pages)【它的本质就是一个Servlet】
JSP是简化Servlet编写的一种技术,它将Java代码和HTML标签混合在同一个文件中编写,页面动态资源使用java代码,页面静态资源使用html标签。
简单来说:可以在html页面中嵌套java代码
作用:简化书写,展示动态页面
1.2 快速入门
1.3 工作原理
1.4 脚本和注释
脚本
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>jsp脚本</title></head><body><!--声明脚本:以前在类中方法外,能书写什么java代码,这个脚本中就可以写什么样的java代码--><%!// 此处可以定义成员变量int number = 100;// 定义方法public static int getSum(int a,int b){return a + b;}%><!--输出脚本:在service方法中进行数据的输出--><%=number%><!--java代码片段脚本:以前在java类里面的方法中能书写什么java代码,这个脚本中就可以书写什么样的java代码--><%// 这里定义了一个局部变量int count = 10;// 调用方法int sum = getSum(10, 20);%><!--输出脚本:在service方法中进行数据的输出--><%=count%><!--输出脚本:在service方法中进行数据的输出--><%=sum%></body>
</html>
注意: jsp一次编译可以多次运行(不需要重新编译,除非你修改了jsp源码)
注释
1.5 指令
page指令
include指令(静态包含)
taglib指令(铺垫明天的知识)
1.6 内置对象
pagecontext内置对象【注意全域查找方法】
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>pageContext域对象</title></head><body><%--模拟Servlet向四个域对象中设置值--%><%// 向page域中设置值//pageContext.setAttribute("book","西游记");// 向request域中设置值//request.setAttribute("book","红楼梦");pageContext.setAttribute("book","红楼梦",2);// 向session域中设置值session.setAttribute("book","三国演义");// 向servletContext域中设置值application.setAttribute("book","水浒传");%><%--从四个域中获取数据--%><%=pageContext.getAttribute("book")%><br><%--<%=pageContext.getAttribute("book",1)%><br><%=pageContext.getAttribute("book",2)%><br><%=pageContext.getAttribute("book",3)%><br><%=pageContext.getAttribute("book",4)%><br>--%><%--全域查找方法:从小范围到大范围挨个找,知道找到就不继续找,没有找到就继续,所有域都没找到返回null--%><%=pageContext.findAttribute("book")%></body>
</html>
1.7 JSP动作标签
动态包含
请求转发
第二章 MVC模式
2.1 JSP发展史
2.2 MVC介绍
DAY08
回顾
第一章 EL表达式
1.1 从域中获取普通单值
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>EL表达式获取域中的数据</title></head><body><h3>EL表达式获取域中的普通单值</h3><%--这里嵌套java片段,模拟在Servlet中向域中设置值--%><%// page域//pageContext.setAttribute("book","西游记");// request域pageContext.setAttribute("book","三国演义",2);// session域pageContext.setAttribute("book","红楼梦",3);// servletContext域pageContext.setAttribute("book","水浒传",4);%><%--使用jsp脚本从域中获取值--%><%=pageContext.getAttribute("book",1)%><br><%=pageContext.getAttribute("book",2)%><br><%=pageContext.getAttribute("book",3)%><br><%=pageContext.getAttribute("book",4)%><br><br><%--全域查找方法--%><%=pageContext.findAttribute("book")%><!-- 使用jsp输出脚本获取到的数据没拿到显示的是null --><%--使用el表达式从域中获取数据--%>${pageScope.book}<br>${requestScope.book}<br>${sessionScope.book}<br>${applicationScope.book}<br><br><!--全域查找-->${book}</body>
</html>
1.2 从域中获取数组中的数据
1.3 从域中获取List集合中的数据
1.4 从域中获取Map集合中的数据
以后,我们在Servlet中,去查询数据库的数据,得到多一些数据,可能需要封装到map,此时,将map数据保存到域中,然后跳转到jsp页面
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>EL表达式获取域中的数据</title></head><body><h3>EL表达式获取域中的Map集合里面的数据</h3><%--这里嵌套java片段,模拟在Servlet中向域中设置值--%><%// 定义集合HashMap<String,String> map = new HashMap<>();// 添加数据map.put("username","健哥哥");map.put("age","18");map.put("address","东京");map.put("singleton","yes");// 将Map集合添加到域中pageContext.setAttribute("map",map);%><!--获得Map集合中的居住人地: 东京-->${map.address}<br>${map['address']}<br>${map["address"]}</body>
</html>
注意: map里面的数据是双列的,获得值有多种写法
1.5 从域中获取JavaBean里面的数据
以后我们经常在Servlet中处理的数据封装到一个对象中去!然后将这个对象保存域中,跳转到jsp页面
比如:用户登录
JavaBean
public class Student implements Serializable {private String name;private String age;private String address;public Student() {}public Student(String name, String age, String address) {this.name = name;this.age = age;this.address = address;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
获取域中JavaBean里面的数据
1.6 从域中获取多个对象构成的集合里面的数据
<%@ page import="com.itheima.domain.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>EL表达式获取域中的数据</title></head><body><h3>EL表达式获取域中的JavaBean里面的数据</h3><%--这里嵌套java片段,模拟在Servlet中向域中设置值--%><%// 创建多个Student对象Student student1 = new Student("健哥哥1","18","东京1");Student student2 = new Student("健哥哥2","28","东京2");Student student3 = new Student("健哥哥3","38","东京3");Student student4 = new Student("健哥哥4","48","东京4");Student student5 = new Student("健哥哥5","58","东京5");// 创建集合ArrayList<Student> students = new ArrayList<>();// 将多个有数据的学生对象添加到集合中students.add(student1);students.add(student2);students.add(student3);students.add(student4);students.add(student5);// 将多个student对象构成的list集合添加到域中pageContext.setAttribute("students",students);%><!--获得多个student对象中的名字: 健哥哥4-->${students[3].name}<br>${students[3]['name']}<br>${students[3]["name"]}<br></body>
</html>
1.7 EL表达式取值的小结
1.8 EL表达式进行运算
1.9 EL表达式操作WEB常用对象
第二章 jstl标签
前面我们知道,jsp2.0规范要求页面尽量少些java代码,el表达式能够取代输出脚本,奔着这个目标,也希望将java代码片段也使用标签(jstl给它取代了,但是,没有完全实现了!!!
jstl标签其底层依旧是java代码!只不过,我们使用标签就行(它会自动执行该标签对应的java代码),方便后期的维护!
2.1 jstl标签的基本使用步骤
2.2 jstl常用标签
jstl标签一般会配合el表达式使用【在Servlet中向域里面设置值,然后跳转jsp页面,在jsp页面使用el表达式从域中取出数据,然后使用jstl标签进行处理】
if标签
choose标签
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><head><title>Title</title></head><body><h3>choose标签</h3><!-- 如果年龄超过18岁,那么允许进入网吧上网 --><!-- 向域中设置数据: 保存用户年龄的数据 【下面的标签等价于:request.setAttribute("age","20"); 】 --><c:set scope="request" var="age" value="8"></c:set><c:choose><%--这个when类似于java中的if--%><c:when test="${age >=18}">哥们,你可以自行进入网吧上网了。。。</c:when><%--这个when类似于Java中的else if--%><c:when test="${age>=10}">哥们,你可以在父母的陪同下进入网吧上网。。。</c:when><%--otherwise类似于java的else--%><c:otherwise>小毛孩,赶紧回家,不要让大人担心。。。</c:otherwise></c:choose></body>
</html>
foreach标签
<%@ page import="com.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><head><title>Title</title></head><body><h3>forEach标签</h3><!--模拟Servlet,向域中设置多个对象构成的集合--><%// 创建多个Student对象Student student1 = new Student("健哥哥1","18","东京1");Student student2 = new Student("健哥哥2","28","东京2");Student student3 = new Student("健哥哥3","38","东京3");Student student4 = new Student("健哥哥4","48","东京4");Student student5 = new Student("健哥哥5","58","东京5");// 创建集合ArrayList<Student> students = new ArrayList<>();// 将多个有数据的学生对象添加到集合中students.add(student1);students.add(student2);students.add(student3);students.add(student4);students.add(student5);// 将多个student对象构成的list集合添加到域中pageContext.setAttribute("students",students);%><!-- 使用jstl标签将域中的数据获取并遍历(多个学生对象构成的list集合) --><table border="1px" align="center" width="600px" height = "230px"><tr><th>用户名</th><th>年龄</th><th>居住地</th></tr><!-- 先判断--><c:if test="${not empty students}"><c:forEach items="${students}" var="student" begin="0" end="4" step="2" varStatus="vs"><tr align="center"><td>${vs.count}</td><td>${student.name}</td><td>${student.age}</td><td>${student.address}</td></tr></c:forEach></c:if></table></body>
</html>
第三章 三层架构
DAY09
回顾
第一章 Filter概述
生活中的过滤器
净水器、空气净化器、地铁安检、山大王
web中的过滤器
当用户访问服务器资源时,过滤器将请求拦截下来,完成一些通用的操作
应用场景
如:登录验证、统一编码处理、敏感字符过滤
保安大叔对胸卡的检查就是一个过滤器~
第二章 Filter快速入门
需求:用户访问某个jsp页面,在访问到达目标资源jsp页面之前,我们添加一个过滤器
2.1 xml配置
(1)编写java类,实现filter接口
import javax.servlet.*;
import java.io.IOException;/*过滤器类: 对quick.jsp过滤1. 编写的一个类去实现Filter接口(需要重写接口中所有的抽象方法)2. 在web.xml文件中配置(配置你要过滤的访问资源路径与过滤器处理类的对应关系)*/
public class QuickFilter implements Filter {// 空实现(没有方法体)@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}/*对目标资源进行过滤器的核心方法*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {// 是否放行chain.doFilter(servletRequest,servletResponse); // 不写这行代码,就是不放行}@Overridepublic void destroy() {}
}
(2)配置web.xml
2.2 注解配置
注意:玩注解的话,需要把web.xml中filter标签注释
(1)编写java类,实现filter接口
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;/*过滤器类: 对quick.jsp过滤1. 编写的一个类去实现Filter接口(需要重写接口中所有的抽象方法)2. 在实现类上面添加一个注解 @WebFilter(urlPatterns = "/jsp/quick.jsp")*/
@WebFilter(urlPatterns = "/jsp/quick.jsp")
public class QuickFilter implements Filter {// 空实现(没有方法体)@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}/*对目标资源进行过滤器的核心方法*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {System.out.println("已经进入过滤器了。。。");// 是否放行//chain.doFilter(servletRequest,servletResponse); // 不写这行代码,就是不放行}@Overridepublic void destroy() {}
}
(2)配置@WebFilter
第三章 Filter工作原理
第四章 使用细节
4.1 生命周期
import javax.servlet.*;
import java.io.IOException;/*Filter的生命周期:一个对象从创建到销毁的过程*/
public class AFilter implements Filter {// 构造方法public AFilter(){System.out.println("AFilter创建了。。。");}// 初始化方法@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("AFilter正在进行初始化。。。");}// 拦截过滤方法@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("AFilter正在对a.jsp目标资源进行过滤。。。");// 放行filterChain.doFilter(servletRequest,servletResponse);}// 销毁方法@Overridepublic void destroy() {System.out.println("AFitler销毁了。。。");}
}
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;/*FilterConfig重点关注获得ServletContext对象*/
public class BFilter implements Filter {// 初始化方法@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 获得当前Filter的名字System.out.println(filterConfig.getFilterName());// 可以获得配置的所有参数名称Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();while (initParameterNames.hasMoreElements()){String name = initParameterNames.nextElement();System.out.println(name);// 可以获得配置的指定参数的值System.out.println(filterConfig.getInitParameter(name));}// 获得ServletContext对象System.out.println(filterConfig.getServletContext().getContextPath());}// 拦截过滤方法@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {}// 销毁方法@Overridepublic void destroy() {}
}
4.2 拦截路径
4.3 拦截方式
xml版本
注解版本
4.4 过滤器链
4.5 注解和xml使用
第五章 综合案例
5.1 用户评论留言
需求
用户访问某论坛网站,可以对文章比赛等内容进行留言
需求分析
代码实现
5.2 统一网站编码(请求和响应)
需求
tomcat8.5版本中已经将get请求的中文乱码解决了,但是post请求还存在中文乱码浏览器发出的任何请求,通过过滤器统一处理中文乱码
需求分析
代码实现
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*处理全站中文乱码的过滤器*/
@WebFilter(filterName = "EncodingFilter",urlPatterns = "/*")
public class EncodingFilter implements Filter {public void destroy() {}public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {System.out.println("进来了。。。");// 对req和resp进行强转HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;// 获得用户请求方式String method = request.getMethod();System.out.println(method);// 判断if("post".equalsIgnoreCase(method)){// 处理post请求中文乱码request.setCharacterEncoding("utf-8");}// 处理响应中文乱码response.setContentType("text/html;charset=utf-8");// 放行chain.doFilter(request, response);}public void init(FilterConfig config) throws ServletException {}}
5.3 非法字符拦截
需求
当用户发出非法言论的时候,提示用户言论非法警告信息
需求分析
代码实现
(2)WordsFilter
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;/*屏蔽非法字符*/
@WebFilter(filterName = "WordFilter",urlPatterns = "/WordsServlet")
public class WordFilter implements Filter {// 定义集合private List<String> wordList = new ArrayList<>();public void destroy() {}public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {//System.out.println(wordList);// 强转HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;// 获得用户输入的内容String content = request.getParameter("content");//System.out.println(content);// 遍历集合for (String word : wordList) {// word: 一个一个的既定非法字符// 判断用户输入的内容是否包含了既定非法字符if(content.contains(word)){// 非法了response.getWriter().write("您的评论含有非法字符,网络警察已关注!");// 不放行return;}}chain.doFilter(req, resp);}/*读取配置文件,已经设定好的非法字符*/public void init(FilterConfig config) throws ServletException {// 加载配置文件数据到对象ResourceBundle bundle = ResourceBundle.getBundle("data");// 读指定key的值String keywords = bundle.getString("keywords");try {// 本身文件是utf-8的,但是服务器拿数据,采用iso8859-1编码的,此时出现的乱码,解回来重新编码keywords = new String(keywords.getBytes("iso8859-1"),"utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 切割String[] words = keywords.split(",");// 遍历获得单个for (String word : words) {// 添加到集合wordList.add(word);}}
}
5.4 非法字符过滤
需求
当用户发出非法言论的时候,在servlet中输出的时候:用"*"替代
你是个笨蛋–>你是个**
我们希望,在获得用户输入的数据时候就已经拿到了处理好的数据(已经将非法字符屏蔽了)
用户在页面表单输入:孙子,你好!
调用request.getParameter(“content”)拿到的数据是**,你好!
技术分析
/*回顾装饰(器)模式*/
public class TestDecorator {public static void main(String[] args) {Phone phone = new Lvjing(new Meiyan(new HuaWei()));phone.take();phone.call();}}// 接口规范
interface Phone {void take();void call();
}// 被包装类,一会对他增强
class HuaWei implements Phone {@Overridepublic void take() {System.out.println("3200W像素拍照");}@Overridepublic void call() {System.out.println("打电话");}
}// 包装抽象类,做一个默认的实现,调用原有的功能
abstract class PhoneWrapper implements Phone {private Phone phone;public PhoneWrapper(Phone phone) {this.phone = phone;}@Overridepublic void take() {phone.take();}@Overridepublic void call() {phone.call();}
}// 美颜增强
class Meiyan extends PhoneWrapper {public Meiyan(Phone phone) {super(phone);}@Overridepublic void take() {// 调用拍照的原有功能super.take();System.out.println("美颜...");}
}// 滤镜增强
class Lvjing extends PhoneWrapper {public Lvjing(Phone phone) {super(phone);}@Overridepublic void take() {super.take();// 原有功能System.out.println("滤镜");}
}
需求分析
代码实现
注意:需要将WordsFilter过滤器的注解注释
(1)自定义MyHttpServletRequest
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.List;/*装饰者:1.装饰类要与被装饰类(HttpServletRequestWrapper:里面的getParameter方法只能获得用户输入的参数数据)一样,实现共同的父接口或者继承共同的父类2.装饰类中需要提供一个带参(默认实现类,其他我们需要的对象)构造!3.在装饰类中提供一个成员变量4.对需要增强的方法进行重写5.不需要重写的,继承(直接拥有了父类的功能),实现接口(重写额方法体内部,调用默认实现类的方法)*/
public class MyHttpServletRequest extends HttpServletRequestWrapper {// 非法词库private List<String> wordList;public MyHttpServletRequest(HttpServletRequest request) {super(request);}@Overridepublic String getParameter(String name) {// 调用原有的功能,获取用户输入的值String parameter = super.getParameter(name);// 对非法词库过滤...for (String word : wordList) {// word: 一个一个的既定非法字符// 判断用户输入的内容是否包含了既定非法字符if(parameter.contains(word)){StringBuilder sb = new StringBuilder();for (int i = 0; i < word.length(); i++) {sb.append("*");}parameter=parameter.replace(word,sb);}}return parameter;}
}
(2)编写WordsProFilter
package com.itheima.web.filter;import com.itheima.web.servlet.MyHttpServletRequest;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;@WebFilter("/WordsServlet")
public class WordsProFilter implements Filter {private List<String> wordList;public void init(FilterConfig config) throws ServletException {// 1.加载配置文件/*ResourceBundle这哥们 专门读取src目录下的properties配置文件,不需要写后缀名*/ResourceBundle words = ResourceBundle.getBundle("words");// 2.读取keyword关键字内容String keyword = words.getString("keyword"); // 傻叉,大爷的,二大爷的// 3.split切割,转为list集合wordList = Arrays.asList(keyword.split(","));System.out.println("加载非法词库:"+wordList);}public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException {// 向下转型HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;// 对request对象进行包装 (过滤)MyHttpServletRequest requestPro = new MyHttpServletRequest(request, wordList);// 放行chain.doFilter(requestPro, response);}public void destroy() {}}
附录
Filter模板设置
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
@javax.servlet.annotation.WebFilter("/${Entity_Name}")
public class ${Class_Name} implements javax.servlet.Filter {public void init(javax.servlet.FilterConfig config) throws javax.servlet.ServletException {}public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, javax.servlet.FilterChain chain) throws javax.servlet.ServletException, java.io.IOException {// 放行chain.doFilter(servletRequest, servletResponse);}public void destroy() {}}
DAY10 Listener&综合案例
回顾
第一章 综合案例
1.1 环境搭建
创建模块(项目)
省略
导入案例原型
加入操作需要的jar包
导入案例需要的数据
导入案例需要的JavaBean
1.2 用户查询功能
需求
使用三层架构和MVC模式开发代码,完成用户显示列表功能。
查询所有用户信息的执行流程
页面入口代码(index.html)
UserServlet
/*用户模块web层*/
@WebServlet(name = "UserServlet", urlPatterns = "/UserServlet")
public class UserServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");// 获得请求参数actionString action = request.getParameter("action");// 判断if("findAllUser".equals(action)){// 要进行查询所有用户信息的功能findAllUser(request,response);}}/*查询所有用户信息的方法*/public void findAllUser(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {// 直接调用service层查询所有用户信息的方法UserService service = new UserService();List<User> users = service.findAllUser();System.out.println(users);// 将查询的集合结果数据保存到request域中request.setAttribute("users",users);// 转发到list.jsp页面request.getRequestDispatcher("/list.jsp").forward(request,response);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
UserService
UserDao
list.jsp页面
1.3 添加用户功能
需求
点击添加用户跳转添加用户页面,在添加用户页面,添加新的用户
添加用户信息执行流程
add.html入口页面
UserServlet
UserService
UserDao
1.4 删除用户功能
需求
点击删除按钮删除当前一整行数据,删除之后重新查询全部展示删除效果
删除指定用户信息的执行流程
list.jsp页面
UserServlet
UserService
UserDao
1.5 修改用户功能
用户回显【异步实现】
需求
点击"修改"按钮,跳转到更新页面(回显数据)
异步操作:请求在哪个页面发起,那么从服务器端得到的数据就先显示在哪个页面
修改用户
需求
重写输入用户信息,点击提交,更新系统
DAY11 AJAX&文件上传
回顾
第一章 JSON回顾
1.1 json知识点的核心
1.2 json格式数据的定义和获取
json数据的key都是字符串类型的,值可以是任意类型的
1.3 java对象转成json格式数据
将单个对象转成json格式数据
将多个对象构成的List集合转成json
/*多个对象构成的List集合转成json格式的数据
*/@Testpublic void test2() throws JsonProcessingException {// 创建一个集合对象ArrayList<Person> persons = new ArrayList<>();// 创建多个Person对象Person p1 = new Person("p001","jack","北京顺义");Person p2 = new Person("p002","jerry","河北邯郸");Person p3 = new Person("p003","rose","湖南郴州");Person p4 = new Person("p004","tom","四川成都");Person p5 = new Person("p005","lucy","山东烟台");// 将多个对象添加到集合persons.add(p1);persons.add(p2);persons.add(p3);persons.add(p4);persons.add(p5);/////上面代码仅仅只是在模拟以后从数据库查询出来的结果数据////////// 将多个对象转成json格式的数据ObjectMapper om = new ObjectMapper();String str = om.writeValueAsString(persons);System.out.println(str);// [{"pid":"p001","pname":"jack","paddress":"北京顺义"},{"pid":"p002","pname":"jerry","paddress":"河北邯郸"},{"pid":"p003","pname":"rose","paddress":"湖南郴州"},{"pid":"p004","pname":"tom","paddress":"四川成都"},{"pid":"p005","pname":"lucy","paddress":"山东烟台"}]}
第二章 案例:检查用户名是否可用
需求
在用户注册页面,输入用户名,当用户名输入框失去焦点时,发送异步请求,将输入框的用户名传递给服务器进行是否存在的校验。
2.1 技术分析
2.2 功能的执行流程
2.3 代码实现
UserServlet
为了演示对象转json数据,这里强加了
UserServlet
/*用户名异步校验web层*/
@WebServlet(name = "UserServlet", urlPatterns = "/UserServlet")
public class UserServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");// 获得请求参数usernameString username = request.getParameter("username");//System.out.println(username);// 调用service层根据用户名查询用户信息的方法UserService service = new UserService();User user = service.findUserByUsername(username);// 将查询结果转成json格式数据ObjectMapper om = new ObjectMapper();String json = om.writeValueAsString(user);//System.out.println(json);// 直接通过响应体响应response.getWriter().write(json);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
register.jsp页面回调函数
$.ajax({url:"${pageContext.request.contextPath}/UserServlet",type:"post",data:{"username":username},success:function(user){// 判断if(user==null){// 说明该用户名可用$("#usernameinfo").html('<span class="label label-success">用户名可用</span>');// 将注册按钮的禁用状态取消
$("#sub").prop("disabled",false);}else{// 说明该用户名不可用$("#usernameinfo").html('<span class="label label-danger">用户名不可用</span>');// 禁用注册提交按钮$("#sub").prop("disabled",true);}},dataType:"json"});
第三章 案例:文件上传
3.1 技术分析
文件上传三要素
补充
文件上传技术
1.使用apache提供工具类commons-fileupload (今天讲,最麻烦的…)
2.使用servlet3.0版本,通过注解实现(黑马旅游网)
3.使用springMVC框架(最简单,底层使用commons-fileupload)
3.2 代码实现【抄一遍即可】
FileUploadServlet
/*文件上传Servlet*/
@WebServlet(name = "FileUploadServlet", urlPatterns = "/FileUploadServlet")
public class FileUploadServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {response.setContentType("text/html;charset=utf-8");// 1.创建磁盘文件项的工厂对象DiskFileItemFactory factory = new DiskFileItemFactory();// 2.通过磁盘文件项工厂对象创建文件上传核心对象ServletFileUpload fileUpload = new ServletFileUpload(factory);try {// 3. 解析请求(request),获得所有的表单项List<FileItem> fileItems = fileUpload.parseRequest(request);//System.out.println(fileItems.size()); // 2// 4. 遍历集合for (FileItem fileItem : fileItems) {// 5. 判断if(fileItem.isFormField()){ // fileItem.isFormField() 结果为true,说明是一个普通项// 获得name属性值String username = fileItem.getFieldName();//System.out.println("普通项username的名字是:" + username); // 获得name属性的值// 获得value属性值String value = fileItem.getString();//System.out.println("普通项username的值是:" + value); // 获得value属性的值// 接下来,具体普通项代码如何编写,取决于需求}else{// 6. 说明是文件上传项,获得文件上传项的名称String filename = fileItem.getName();//System.out.println(filename); // temp.jpg// 7. 根据文件上传的名称和存储的位置,创建输出流String realPath = getServletContext().getRealPath("/upload");//System.out.println(realPath);// 8. 判断upload目录在服务器中是否存在File file = new File(realPath);if(!file.exists()){// 不存在,创建一个file.mkdirs();}//System.out.println(realPath);OutputStream os = new FileOutputStream(realPath + "/" + filename);// 9. 获得输入流InputStream is = fileItem.getInputStream();// 10. 流拷贝IOUtils.copy(is,os);// 11. 释放资源os.close();is.close();// 12. 给出友好提示response.getWriter().write("success!");}}} catch (FileUploadException e) {e.printStackTrace();}}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}}
第四章 Listener
4.1 概述
生活中的监听器
我们很多商场有摄像头,监视着客户的一举一动。如果客户有违法行为,商场可以采取相应的措施。
javaweb中的监听器
在我们的java程序中,有时也需要监视某些事情,一旦被监视的对象发生相应的变化,我们应该采取相应的操作。监听web三大域对象:HttpServletRequest、HttpSession、ServletContext
4.2 快速入门
监听器在web开发中使用的比较少;见的机会就更少了,今天我们使用ServletContextListenner来带领大家学习下监听器,因为这个监听器是监听器中使用率最高的一个,且监听器的使用方式都差不多。
我们使用这个监听器可以在项目启动和销毁的时候做一些事情,例如,在项目启动的时候加载配置文件。
编写监听类实现对应的监听器接口
/*域对象本身监听器,关注的是域对象的创建和销毁!ServeltContext:创建:服务器启动创建销毁:服务器停止销毁事件源:ServletContext对象事件:创建和销毁监听器: MyServletContextListener注册监听:在web.xml文件中配置事件对象:可以获得事件源对象!只要ServletContext创建了或者销毁了,那么就会被监听器MyServletContextListener捕获到,从而执行对应的方法!*/
public class MyServletContextListener implements ServletContextListener {// 当ServletContext被创建的时候会执行@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {System.out.println("已监听到ServletContext创建了");System.out.println("去加载spring框架的配置文件");// 通过事件对象获得事件源对象ServletContext context = servletContextEvent.getServletContext();}// 当ServletContext对象销毁的时候被执行!@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {System.out.println("已监听到ServeltContext对象销毁了");}}
xml配置
注解配置
4.3 案例:统计在线人数
需求
有用户使用网站,在线人数就+1;用户退出网站,在线人数就-1
监听器
/*域对象属性监听器关注的是对域对象属性值的变更(添加、替换、删除)*/@WebListener()
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener, HttpSessionListener {// 向session中添加新的值就执行这个方法@Overridepublic void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {System.out.println("向session域中设置值了");}// 将session域中的数据删除了,就执行这个方法@Overridepublic void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {System.out.println("将session域中值删除了");}// 将session域中的数据替换就会执行这个方法@Overridepublic void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {System.out.println("将session域中值替换了");}////////////////////上面三个方法是为了演示域对象属性监听器【与本案例无关】//////////////////////// session对象创建就执行这个方法@Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {//System.out.println("session创建了");// 会话创建,有新的用户在访问网站HttpSession session = httpSessionEvent.getSession();// 获得项目环境ServletContext servletContext = session.getServletContext();// 获得会话的idSystem.out.println("session创建了。。。"+ session.getId());// 获取当前在线人数Integer number = (Integer) servletContext.getAttribute("NUMBER");// 判断if(number==null){// 第一个用户servletContext.setAttribute("NUMBER",1);}else{// 不是第一个servletContext.setAttribute("NUMBER", ++number);}}// session对象销毁执行这个方法@Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {// 会话结束,用户就不在线了HttpSession session = httpSessionEvent.getSession();// 获得ServletContextServletContext context = session.getServletContext();System.out.println("session销毁了。。。"+ session.getId());// 获得当前在线人数Integer number = (Integer) context.getAttribute("NUMBER");// 人数少1个context.setAttribute("NUMBER",--number);}
}
number.jsp
LogoutServlet