Servlet
Servlet的常用方法
//我们创建的一个servlet程序,默认集成HttpServlet,可以在Tomcat服务器上运行.
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public HelloServlet() {
super();
}
/**
* doGet方法可以接收我们浏览器端的请求
* HttpServletRequest request:请求对象 浏览器请求服务器时所带的数据(请求行 请求头 请求正文)全部封装在该对象里面.
* HttpServletResponse response:响应对象 我们可以通过该对象 设置服务器端向浏览器端响应的信息.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//解决向浏览器响应中文乱码 文本当做html解析 指定编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获取请求行
String method = request.getMethod();// 请求方式
String uri = request.getRequestURI();// 请求资源
StringBuffer url = request.getRequestURL();
System.out.println("uri:"+uri);// /web-39/Hello
System.out.println("url:"+url);// http://localhost:8080/web-39/Hello
System.out.println("协议版本号:"+request.getProtocol());// HTTP/1.1
System.out.println("获取远程的ip:"+request.getRemoteAddr());// 访问的ip
//获取请求头(根据请求头获取请求值)
System.out.println("Accept:"+request.getHeader("Accept"));
System.out.println("user-agent:"+request.getHeader("user-agent"));
//获取所有请求头名称(返回枚举类型数据)
Enumeration<String> headerNames = request.getHeaderNames();
System.out.println("--------------All headers-------------------");
while (headerNames.hasMoreElements()) {
String key = headerNames.nextElement();
System.out.println(key+"-->"+request.getHeader(key));
}
//response.getWriter()获得打印流对象 往浏览器页面上打印内容
response.setHeader("Server", "New Header");// 设置响应头
response.getWriter().append("Served at: ").append("Hello Servlet!!!");
}
// doPost方法可以接收我们浏览器端的post请求
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Servlet的三种创建方式
//方式一:继承HttpServlet类
public class Servlet1 extends HttpServlet {
private static final long serialVersionUID = 1L;
/*
* service()方法可以理解为是Servlet程序的主入口,每次请求过来,必须都会先经过service方法,
* service方法里面会获取请求方式getMethod(),然后回去调相应的doGet()或doPost()方法
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("method-->"+req.getMethod());// method-->GET
super.service(req, resp);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("程序会调doGet()方法");
response.getWriter().write("方式一");// 会在浏览器输出
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//方式二:继承GenericServlet类
public class Servlet2 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("Servlet2.service()");
HttpServletRequest request = (HttpServletRequest) req;// 将req强转为http
HttpServletResponse response = (HttpServletResponse) res;
String method = request.getMethod();
if (method.equalsIgnoreCase("get")) {
doGet(request, response);
} else if (method.equalsIgnoreCase("post")) {
doPost(request, response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().write("方式二");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//方式三:实现Servlet接口(了解即可,一般不用)
public class Servlet3 implements Servlet {
@Override
public void init(ServletConfig config) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
Servlet的2种配置方式
<!-- servlet节点就是用来配置 我们servlet信息 servlet3.0之前使用这种方法,3.0以后也可以用 -->
<servlet>
<!--servlet-name:给该servlet 程序起个名字 注意 该名字是唯一的 -->
<servlet-name>HelloServlet</servlet-name>
<!--配置servlet的全限定名:包名.类名 -->
<servlet-class>web.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping:主要是servlet的映射 如何访问该servlet程序 -->
<servlet-mapping>
<!--servlet-name指定servlet的名字 -->
<servlet-name>HelloServlet</servlet-name>
<!--配置servlet如何访问
http://localhost:8080/项目名/hello
唯一
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
//servlet3.0之后在servlet类上面加一个注解就可以了
//@WebServlet("/hello")
//@WebServlet(value="/hello")
@WebServlet(value={"/h1","/h2"})
public class HelloServlet extends HttpServlet {
......
}
Servlet生命周期
Servlet的生命周期
-
实例化 构造方法
默认情况下,当你第一次访问该servlet程序的时候 会去创建该servlet的对象,只创建。
-
初始化 init方法
当初始化的时候 两个init()方法都会被调用, 有些时候我们可能会在servlet初始化的时候去写一些业务代码,这个时候我们的代码可以写在init方法里面。
推荐把我们自己的代码写在无参的init方法里面。init方法只被执行一次
-
service方法
service方法 是servlet程序的主入口,每次访问servlet程序都会走他,他会调用具体的doGet和doPost方法,会被调用n次。
-
destory方法
当servlet程序被销毁的时候 会调用该方法。
被调用1次。
/**
* Servlet的生命周期
*/
public class LifeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public LifeServlet() {
super();
System.out.println("1、完成了实例化");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("2、完成了初始化");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.service(req, resp);
System.out.println("3、调用service方法");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("3、service调用doGet方法,就绪中");
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
@Override
public void destroy() {
super.destroy();
System.out.println("4、销毁了");
}
}
Servlet获取表单数据
doGet(){
request.setCharacterEncoding("utf-8");//用来解决post请求乱码
//get请求 tomcat8及以上不会出现乱码。 tomcat7或者以下,get请求会出现乱码:需要自己手动解码。
//获取表单数据
String name=request.getParameter("username");
String pwd=request.getParameter("password");
String[] hb = request.getParameterValues("hobby");//获取多个参数值一般用来获取复选框的值
Enumeration<String> names = request.getParameterNames();//获取所有参数名称(枚举类型)
while (names.hasMoreElements()) {//遍历枚举
String key = names.nextElement();
System.out.println(key+"-->"+request.getParameter(key));
}
Map<String, String[]> map = request.getParameterMap();
}
Servlet重定向
//1.重定向是客户端行为
//2.重定向是浏览器做了至少两次的访问请求的
//3.重定向浏览器地址改变
//4.重定向2次跳转之间传输的信息会丢失
//5.重定向可以指向任何的的资源.如百度
doGet(){
//重定向有两种方式
//方式一
response.setStatus(302);//设置状态码302
response.setHeader("Location","1.html");
//方式二:一般使用该方式
response.sendRedirect("1.html");
response.sendRedirect("http://www.baidu.com");//指向到其他网站
}
Servlet转发
//1.转发是服务器行为
//2.转发是浏览器只做了一次访问请求
//3.转发浏览器地址不变
//4.转发2次跳转之间传输的信息不回丢失,所以可以通过request进行数据的传递
//5.转发只能将请求转发给同一个web应用中的组件(只能在当前项目下进行转发 不能转发到外网去)
doGet(){//s1
request.setAttribute("list",Arrays.asList("jack","rose"));//request域对象存数据
request.getRequestDispatcher("s2").forward(request,respone);//路径前面不能加项目名
}
doGet(){//s2
List<String> list=(List<String>) request.getAttribute("list");//从request域对象取出数据
request.removeAttribute("list");//通过key来删掉域对象内容
}
ServletConfig
ServetConfig对象主要用于加载servlet配置参数信息。
<servlet>
<!--配置全局的servlet的初始化信息参数 -->
<init-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</init-param>
<description></description>
<display-name>My1</display-name>
<servlet-name>My1</servlet-name>
<servlet-class>web14.My1</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
doGet(){
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String name = getInitParameter("name");//得到name参数
response.getWriter().append(name);
}
ServletContext(上下文对象)
request.setCharacterEncoding("utf-8");//用来解决post请求乱码
response.setContentType("text/html;charset=utf-8");
//获取ServletContext对象存数据
//获取ServletContext
// this.getServletConfig().getServletContext(); //方式一
// this.getServletContext();//方式二
ServletContext context = request.getServletContext();//一般用这种方式
//作用
//1.获取真实路径
//获取当前项目的发布路径
String path = context.getRealPath("/");
System.out.println(path);//D:\web\apache-tomcat-8.0.43\webapps\web-39\
//2.获取容器的附加信息
System.out.println(context.getServerInfo());//Apache Tomcat/8.0.43
System.out.println(context.getContextPath());// /web-39
//3.全局容器
context.setAttribute("msg", "共享信息");//设置信息到全局容器中
System.out.println(context.getAttribute("msg"));//获取数据
context.removeAttribute("msg");//移除数据
//特点:
//唯一性:一个应用对应一个servlet上下文
//一直存在:只要容器不关闭或者应用不卸载,servlet上下文就一直存在.
Cookie
doGet(){//s1
// 如何创建Cookie
// 方式一:通过响应头的方式来存储Cookie(了解)
// response.setHeader("set-Cookie", "name=chengp");//set-Cookie和set-cookie均可
// 方式二:创建Cookie 只是在内存里面创建
Cookie c1 = new Cookie("name", "chengp");
Cookie c2 = new Cookie("age", "27");
Cookie c3=new Cookie("Chinese", URLEncoder.encode("中文","utf-8"));//存中文要用URLEncoder编码
c1.setValue("cookieValue");// 设置Cookie的属性(修改cookie的值)
c1.setDomain("localhost");// 设置域名(一般默认 不写)
c1.setPath("/");// 默认是当前项目名(一般不写)
c1.setMaxAge(60 * 60 * 24 * 30);// 设置cookie的最大时长,单位是秒,
c2.setMaxAge(-1);//cookie的默认级别(会话级别),浏览器关了cookie失效。
c3.setMaxAge(0);//让Cookie失效,无法读取
response.addCookie(c1);//存储Cookie
response.addCookie(c2);
response.addCookie(c3);
response.getWriter().append("Served at: add").append(request.getContextPath());
}
doGet(){
// 如何取出Cookie
// 方式一:通过请求头的方式来获取Cookie (了解)
// String cookie = request.getHeader("Cookie");//Cookie和cookie均可
// response.getWriter().append(cookie);
// 方式二:获取所有的Cookie 只是获取当前域名的和当前路径的,没有cookie是null
Cookie[] cookies = request.getCookies();// 返回Cookie数组
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
// System.out.println(cookie.getName()+"-->"+cookie.getValue());
// 删除某个Cookie
if (cookie.getName().equals("age")) {
cookie.setMaxAge(0);
response.addCookie(cookie);
} else {
System.out.println(cookie.getName() + "-->" + URLDecoder.decode(cookie.getValue(), "utf-8"));// 解码Cookie
}
}
}
}
Session
doGet(){//s1
// 创建或得到Session对象
HttpSession session = request.getSession();
// HttpSession session2 = request.getSession(true);//true等同于与无参
// session对象操作会话数据(域对象)
session.setAttribute("name", Arrays.asList("chengp", "zhangsan", "lisi"));// 存
session.setMaxInactiveInterval(60 * 60);// 默认是30分钟,从你最后一次访问该session的时间算起。
// 手动去存储一个cooke 时长设置与session同步
Cookie cookie = new Cookie("JSESSIONID", session.getId());// 得到session对象编号
cookie.setMaxAge(60 * 60);
response.addCookie(cookie);
}
doGet(){//s2
HttpSession session = request.getSession();// 创建Session对象
Object name = session.getAttribute("name");// 获得数据
System.out.println(name);// [chengp, zhangsan, lisi]
session.removeAttribute("name");// 清除数据
session.invalidate();// 销毁session对象
}
JSP
JSP语法
<%--指令,页面的设置 --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--1.模板元素 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一个JSP页面</title>
</head>
<body>
<%--我是JSP特有的注释,不会出现在对应的java类中的 --%>
<!-- 我是HTML的注释,会写出到页面 -->
<a href="http://www.baidu.com">百度一下</a>
<%--JSP脚本 --%>
<%! private int count; %> <%--声明全局变量,带!的意思是声明 --%>
<!-- 声明并且实现方法 -->
<%!public void show(){
System.out.println("count");
}%>
<%!private int age=10; %>
<%-- <%!show();%> --%>
<!-- JSP脚本之方法内使用 -->
<!-- 局部变量 -->
<%int c=1; %>
<%count++;c++;%>
<%
System.out.println("局部变量:"+c);
System.out.println("全局变量:"+count);
%>
<%System.out.println("请求的IP地址:"+request.getRemoteAddr());%>
<!-- JSP脚本之三:赋值、输出内容 -->
<h1>访问次数:<%=count %></h1>
</body>
</html>
JSP-Page指令
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
session="true"
buffer="8kb"
errorPage="error.jsp"
isErrorPage="false"
isELIgnored="false"
%>
<%-- 以上属性都是默认值,一般不写 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Date date=new Date();//会导入<%@page import="java.util.Date"\%\>这个包
out.write("out");//JspWriter往页面打印数据,不会立马把数据写到页面上,会先把数据写到缓冲区
//缓冲区写满了或者jsp运行完了,才会把数据写到页面上
out.flush();//刷新缓冲区,写出数据
//jsp使用session对象
response.getWriter().append("hello");//servlet的方式 PrintWriter对象 没有缓冲区
int i=10/0; //会报错 将error.jsp页面内容显示到浏览器
%>
</body>
</html>
JSP-include指令
<body>
<%-- 静态包含:把其它资源包含到当前页面中,在翻译时就把两个文件进行合并--%>
<%--先合并和编译,被包含的jsp文件不应该有html head body等标签。--%>
<%@include file="top.jsp" %>
<%-- 动态包含:不会合并文件,当代码执行到include时,才包含另一个文件的内容 --%>
<jsp:include page="top.jsp"></jsp:include>
</body>
JSP九大内置对象
对象名 | 类型 | 说明 |
---|---|---|
request | javax.servlet.http.HttpServletRequest | |
response | javax.servlet.http.HttpServletResponse | |
session | javax.servlet.http.HttpSession | 由session=“true”开关 |
application | javax.servlet.ServletContext | |
exception | java.lang.Throwable | 由isErrorPage=“false”开关 |
page | java.lang.Object (当前对象this) | 当前servlet实例 |
config | javax.servlet.ServletConfig | |
pageContext | javax.servlet.jsp.PageContext | |
out | javax.servlet.jsp.JspWriter | javax.servlet.jsp.JspWriter |
<body>
<h3>可以创建其它的8个隐式对象</h3>
<%
Exception exception=pageContext.getException();
Object page2=pageContext.getPage();
ServletRequest requset2=pageContext.getRequest();
ServletResponse response2=pageContext.getResponse();
ServletConfig config2=pageContext.getServletConfig();
ServletContext application2=pageContext.getServletContext();
HttpSession session2=pageContext.getSession();
JspWriter out2=pageContext.getOut();
%>
</body>
JSP四大域对象
<body>
<h3>四大域对象的范围大小:pageContext<request<session<application</h3>
<%
pageContext.setAttribute("name", "我是pageContext域对象");//只能在当前页面取出
request.setAttribute("name", "我是request域对象");
session.setAttribute("name", "我是session域对象");
application.setAttribute("name", "我是application域对象");//就是ServletContext域对象
%>
<%-- 使用pageContext存放域对象 --%>
<%
pageContext.setAttribute("name", "我是pageContext域",PageContext.PAGE_SCOPE);//PageContext.PAGE_SCOPE==1
pageContext.setAttribute("name", "我是request域",PageContext.REQUEST_SCOPE);//PageContext.REQUEST_SCOPE==2
pageContext.setAttribute("name", "我是session域",PageContext.SESSION_SCOPE);//PageContext.SESSION_SCOPE==3
pageContext.setAttribute("name", "我是application域",PageContext.APPLICATION_SCOPE);//PageContext.APPLICATION_SCOPE==4
%>
<h3>取出域对象内容</h3>
<div>
pageContext域对象内容:<%=pageContext.getAttribute("name")%><br/>
request域对象内容:<%=request.getAttribute("name")%><br/>
session域对象内容:<%=session.getAttribute("name")%><br/>
application域对象内容:<%=application.getAttribute("name")%><br/>
</div>
<h3>使用pageContext取出域对象内容</h3>
<div>
pageContext域对象内容:<%=pageContext.getAttribute("name",1)%><br/>
request域对象内容:<%=pageContext.getAttribute("name",2)%><br/>
session域对象内容:<%=pageContext.getAttribute("name",3)%><br/>
application域对象内容:<%=pageContext.getAttribute("name",4)%><br/>
</div>
<h3>查找域对象内容,从小到大查找</h3>
<%=pageContext.findAttribute("name") %>
</body>
JSP-EL表达式
<body>
<%pageContext.setAttribute("name", "manaphy1",1); %>
<%pageContext.setAttribute("name", "manaphy2",2); %>
<%pageContext.setAttribute("name", "manaphy3",3); %>
<%pageContext.setAttribute("name", "manaphy4",4); %>
<h4>EL表达式指定从某个域对象中进行查找数据</h4>
<div>
${pageScope.name }<br/>
${requestScope.name }<br/>
${sessionScope.name }<br/>
${applicationScope.name }
</div>
<h4>el表达式从4个域对象里面查找:</h4>
<div>
${name }<br/>
JSP表达式找不到是null:<%=pageContext.getAttribute("name2") %><br/>
EL表达式找不到是空串:${name1 }
</div>
<h4>El表达式的运算和三目运算符</h4>
<div>
${1+1 }<!-- 2 -->
${true&&false }<!-- false -->
${100>99 }<!-- true -->
${1 eq '1' }<!-- true -->
${1=='1' }<!-- true -->
${'1' eq '1' }<!-- true -->
${'a' == 'a' }<!-- true -->
${2>1? "2>1":"2<1" }<!-- 2>1 -->
</div>
<%-- jsp里面动态获取项目名 --%>
<div>
<form action="${pageContext.request.contextPath }/login"></form>
</div>
<%-- El表达式存放实体类 --%>
<%
User user=new User(new Address("浙江","杭州"),"张三","12345",new Date(),"男");
User user1=new User(new Address("浙江","温州"),"李四","54321",new Date(),"女");
request.setAttribute("user", user);//存对象
List<User> list=new ArrayList<>();
list.add(user);
list.add(user1);
request.setAttribute("list",list);//存list
Map<String,User> map=new HashMap<>();
map.put("a1", user);
map.put("a2", user1);
request.setAttribute("map", map);
%>
<h4>EL表达式取出域对象中存放的user对象</h4>
<!-- EL表达式中的.表示调用该属性的get方法 -->
<div>
${user }<br/><%-- 表示调用user的toString方法 --%>
${user.uname }<br/><%-- 等同于user.getUname() --%>
${user.address.pro }<br/><%-- 等同于user.getAddress().getPro --%>
</div>
<h4>EL表达式取出域对象中存放的List对象</h4>
<div>
${list }<br/><%-- 等同于sout(list) --%>
${list[0].uname }--->${list.get(0).getUname() }<%-- 张三 --%>
</div>
<h4>EL表达式取出域对象中存放的Map对象</h4>
<div>
${map }<br/><%-- 等同于sout(map) --%>
${map['a1'] }==>${map.a1 }<br/>
${map['a1'].address.city }<%-- 杭州 --%>
</div>
<%
String s1="";
pageContext.setAttribute("s1", s1);
String s2=null;
pageContext.setAttribute("s2", s2);
String s3="12";
pageContext.setAttribute("s3", s3);
List list1=new ArrayList();
pageContext.setAttribute("list1",list1);
%>
<h4>EL表达式判断是否为空</h4>
<!-- empty关键只要内容是空true -->
<div>
${empty s1 }<br/><%-- true --%>
${empty s2 }<br/><%-- true --%>
${empty s3 }<br/><%-- false --%>
${empty s4 }<br/><%-- true --%>
</div>
</body>
JSP-JSTL
JSTL:全称JavaServerPages Standard TagLibrary,JSP标准标签库
作用:实现JSP页面中逻辑处理。如判断, 循环等;
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP-JSTL案例</title>
</head>
<body>
<h4>往域对象存放数据</h4>
<%--
value属性:要存放的值
var属性:通过该值来取出该数据-->key值
scope:存放的域对象 (默认存放page域)
--%>
<div>
<c:set value="张三" var="name" scope="request"></c:set>
${name }=等同于=><c:out value="${name }"></c:out><%-- 张三 --%>
<!-- 移除域对象的数据 --><br/>
<c:remove var="name" scope="request"/>
<!--4.给指定变量赋默认值 -->
<c:out value="${name2 }" default="李四"></c:out>
${name2 }<%-- 李四 --%>
</div>
<h4>条件标签if</h4>
<div>
<c:set scope="request" value="女" var="sex"></c:set>
<c:if test="${sex eq '男'}">
当前域对象sex=男
</c:if>
<c:if test="${!(sex eq '男')}">
当前域对象sex!=男
</c:if><br/>
男:<input type="radio" ${sex eq '男'?"checked=1":"" }>
女:<input type="radio" ${sex eq '女'?"checked=1":"" }>
</div>
<h4>条件标签choose</h4>
<div>
<!-- 可以有多个c:when 和 1个c:otherwise 他们之间只会走一个-->
<c:choose>
<c:when test="${sex eq '男' }">男</c:when>
<c:when test="${sex eq '女' }">女</c:when>
<c:otherwise>人妖</c:otherwise>
</c:choose>
</div>
<h4>foreach标签用来循环</h4>
<%
List<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("c");list.add("d");list.add("e");
pageContext.setAttribute("list", list);
%>
<!--
begin:开始遍历下表 不写从0开始
end:遍历到哪个下表 不写全部遍历
items:要遍历的集合
step:步长 不写默认是1
var:当前正在遍历的集合的对象
varStatus:变量状态:遍历出的每一项内容的状态 获得遍历的个数
-->
<ul>
<c:forEach items="${list}" var="item" varStatus="status">
<li>${item}-->${status.index }</li>
</c:forEach>
</ul>
</body>
</html>
ServletContextListener的构造方法
RequestListener的构造方法,在访问html、jsp、servlet的时候创建
SessionListener的构造方法,访问html不会创建,访问jsp会自动创建,访问servlet时看情况
ServletContextListener初始化
MyFilter2的构造方法
MyFilter2初始化
MyFilter1的构造方法
MyFilter1初始化
-------------执行web/s1后-------------
request初始化
MyServlet的构造方法
requset replace属性org.apache.catalina.ASYNC_SUPPORTED-->true-->替换后的值为false
requset add属性request-->old request
requset replace属性request-->old request-->替换后的值为new request
requset remove属性request-->new request
创建了一个session对象
ServletContext add属性count-->1
当前网站在线人数为:1
session add属性session-->old session
session replace属性session-->old session-->替换后的值为new session
session remove属性session-->new session
ServletContext add属性context-->old context
ServletContext replace属性context-->old context-->替换后的值为new context
ServletContext remove属性context-->new context
request在一次请求完成后被销毁
---------重启服务器后-------
MyFilter2被销毁
MyFilter1被销毁
ServletContextListener被销毁
MVC
第一章 MVC模式简介
1.1 MVC的概念
首先我们需要知道MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),即为MVC。它是一种软件设计的典范,最早为Trygve Reenskaug提出,为施乐帕罗奥多研究中心(Xerox PARC)的Smalltalk语言发明的一种软件设计模式
1.2 MVC模式详解
虽然MVC并不是Java当中独有的,但是现在几乎所有的B/S的架构都采用了MVC框架模式,但是MVC在B/S架构中并没有完全地实现,其实我们根本不需要掌握未实现的部分。
- 控制器Controller:控制器即是控制请求的处理逻辑,对请求进行处理,负责请 求转发;
- 视图View:视图即是用户看到并与之交互的界面,比如HTML(静态资源),JSP(动态资源)等等。
- 模型Model:模型代表着一种企业规范,就是业务流程/状态的处理以及业务规则的规定。业务流程的处理过程对其他层来说是不透明的,模型接受视图数据的请求,并返回最终的处理结果。业务模型的设计可以说是MVC的核心。
1.3 MVC高级框架应用
MVC模式被广泛用于Java的各种框架中,比如Struts2、springMVC等等都用到了这种思想。
Struts2是基于MVC的轻量级的web应用框架。基于MVC,说明基于Struts2开发的Web应用自然就能实现MVC,也说明Struts2着力于在MVC的各个部分为我们的开发提供相应帮助
第二章 JavaWeb的三层架构
2.1 JavaWeb经历三个时期
2.1.1 JSP Model1第一代
JSP Model1是JavaWeb早期的模型,它适合小型Web项目,开发成本低!Model1第一代时期,服务器端只有JSP页面,所有的操作都在JSP页面中,连访问数据库的API也在JSP页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。
2.1.2 JSP Model1第二代
JSP Model1第二代有所改进,把业务逻辑的内容放到了JavaBean中,而JSP页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但还让JSP做了过多的工作,JSP中把视图工作和请求调度(控制器)的工作耦合在一起了。
2.1.3 JSP Model2
JSP Model2模式已经可以清晰的看到MVC完整的结构了。
JSP【View】:视图层,用来与用户打交道。负责接收用来的数据,以及显示数据给用户;
Servlet【controller】:控制层,负责找到合适的模型对象来处理业务逻辑,转发到合适的视图;
JavaBean【model】:模型层,完成具体的业务工作,例如:开启、转账等。
小结:这就是javaweb经历的三个年代,JSP Model2适合多人合作开发大型的Web项目,各司其职,互不干涉,有利于开发中的分工,有利于组件的重用。但是,Web项目的开发难度加大,同时对开发人员的技术要求也提高了。
第三章 三层的使用
第四章Jquery Ajax
4.1 jQuery AJAX简介
什么是 Ajax
简短地说,在不重载整个网页的情况下,AJAX 通过后台加载数据,并在网页上进行显示。
使用 AJAX 的应用程序案例:谷歌地图、腾讯微博、优酷视频、人人网等等。
ajax使用案例:比如在用户注册的时候,用户输入姓名之后,失去焦点之后,立马给用户提示该用户名是否可用,注意此时没有点击提交表单按钮,这就是使用ajax来实现的。
4.2 load方法
jQuery load()方法
$(“div”).load(“地址”,function(data,status,xhr){})
用于把某个资源比如text文本或者js,css.html,jsp文件加载到标签,
第一个参数是资源的地址,
第二个是加载之后执行的函数,data表示加载的内容,status表示是否加载成功
加载成功:status是success
加载失败:status是error
-
data - 包含调用成功时的结果内容
-
status - 包含调用的状态
-
xhr - 包含 XMLHttpRequest 对象 底层的JS内置对象 是使用该对象来进行交互数据的
下面的例子会在 load() 方法完成后显示一个提示框。如果 load() 方法已成功,则显示"外部内容加载成功!",而如果失败,则显示错误消息:
<script type="text/javascript">
$("button").click(function() {
$("#div1").load("demo_test.txt", function(responseTxt, statusTxt, xhr) {
if (statusTxt == "success")
alert("外部内容加载成功!");
if (statusTxt == "error")
alert("Error: " + xhr.status + ": " + xhr.statusText);
});
});
</script>
1.3 get和post方法
jQuery $.get() 方法
$.get() 方法通过 HTTP GET 请求从服务器上请求数据。
语法:$.get(URL,data,callback);
必需的 URL 参数规定您希望请求的 URL。
可选的 data 参数规定连同请求发送的数据。(格式类似于自定义参数)
可选的 callback 参数是请求成功后所执行的函数名。
下面的例子使用 $.get() 方法从服务器上的一个文件中取回数据:
<script type="text/javascript">
$("button").click(function() {
$.get("demo_test.php",{
name:"百度",
url:"http://www.baidu.com"
}, function(data, status) {
alert("数据: " + data + "\n状态: " + status);
});
});
</script>
jQuery $.post() 方法
.get()
1.4 ajax()方法
既可以发送get请求也可以发送post请求。
<script type="text/javascript">
$("button").click(function() {
$.ajax({
url: " ", //地址
data: {
"": ""
}, //多用json数据
type: "get", //get post 默认get
dataType: "json", //json script text html xml 默认会根据返回自动匹配
async: true,//是否使用异步默认设置下,默认true使用异步
cache: true, //false表示不使用缓存 默认true
success: function(data) {},
error: function() {}
});
});
</script>
第五章java解析JSON
5.1 什么是json
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
5.2 json语法
[ ] 表示数组
{ } 表示对象
- " " 表示是属性名或字符串类型的值
- 表示属性和值之间的间隔符
, 表示多个属性的间隔符或者是多个元素的间隔符
5.3 JSON解析
package web;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@SuppressWarnings("all")
public class TestfFunction {
User user1 = new User(101, "张三", new Date(), true);
User user2 = new User(102, "李四", new Date(), false);
List<User> list = Arrays.asList(user1, user2);
@Test
public void gson() {
// 1. 导入Gson的包 Gson是谷歌开源的,用java语言解析json的组件
// 2.创建Gson对象
Gson gson = new Gson();
// 如有日期,则指定日期格式
Gson gson2 = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
// 3.把java对象转成json格式的字符串 toJson(Object obj)
String json = gson2.toJson(user1);// 存对象
String json2 = gson2.toJson(list);// 存集合
System.out.println(json);//不设置getter和setter无影响
System.out.println(json2);
// 4.把json格式的字符串转成java对象 fromJson(String str)
User $user1 = gson.fromJson(json, User.class);
List $list = gson.fromJson(json2, new TypeToken<List<User>>() {
}.getType());
System.out.println($user1);
System.out.println($list);
}
@Test
public void FASTJSON() {
// 导入fastjson包 阿里开源的包
// 把java对象转成json格式的字符串 JSON.toJSONString(Object obj)
String json = JSON.toJSONString(user1);
String json2 = JSON.toJSONString(list);
System.out.println(json);//如果不设置getter和setter不会获取任何数据
System.out.println(json2);
// 把json格式的字符串转成java对象
User parseObject = JSON.parseObject(json, User.class);
List<User> parseArray = JSON.parseArray(json2, User.class);
System.out.println(parseObject);
System.out.println(parseArray);
}
@Test
public void Jackson() throws IOException {
// SpringMvc框架内置的一个java解析json的组件。需要引入3个jar
// 创建Mapper对象
ObjectMapper mapper = new ObjectMapper();
// 把java对象转成json字符串
String json = mapper.writeValueAsString(user1);
String json2 = mapper.writeValueAsString(list);
System.out.println(json); //如果不设置getter和setter只会获取日期
System.out.println(json2);
// 把json字符串转成java对象
User $user1 = mapper.readValue(json, User.class);
Object $list = mapper.readValue(json2, new TypeReference<List<User>>() {});
System.out.println($user1);
System.out.println($list);
}
}
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
public class User {
private int id;
private String name;
@JSONField(format="yyyy-MM-dd") //FASTJSON指定日期格式
@JsonFormat(pattern="yyyy-MM-dd") //Jackson指定日期格式
private Date birthday;
private boolean sex;
public User(int id, String name, Date birthday , boolean sex ) {
this.id = id;
this.name = name;
this.birthday = birthday;
this.sex = sex;
}
@Override
public String toString() {......}
getter() setter()
}
第六章 数据操作
6.1 数据分页
分页的javaBean类的封装PageBean
public class PageBean<T>{
private int currentPage;// 当前页
private int pages;// 总页数
private int pageSzie;// 每页数据大小
private int totalCount;// 分页数据的总条数
private List<T> data;// 每页要显示的数据
public PageBean() {}
@Override
public String toString() {......}
getter() setter()
}
UserDaoImpl关键代码实现
@Override // 根据当前页查询分页数据
public List<Users> queryUsersByPage(int currentPage, int pageSize) {
String sql = "select * from users limit ?,?";
List<Users> list = null;
try {
list = qr.query(sql, new BeanListHandler<>(Users.class), (currentPage - 1) * pageSize, pageSize);
} catch (SQLException e) {
e.printStackTrace();
} finally {
return list;
}
}
@Override // 查询数据总条数
public int queryCount() {
String sql = "select count(uid) from users";
Long count = 0L;//获得的属性必须为Long
try {
count = qr.query(sql, new ScalarHandler<Long>());
} catch (SQLException e) {
e.printStackTrace();
} finally {
return count.intValue();//强转为int
}
}
UserServiceImpl关键代码实现
@Override //根据当前页和每页数据大小获得当前页的用户数据
public PageBean<Users> showUsersByPage(int currentPage, int pageSize) {
PageBean pb=new PageBean<Users>();
pb.setCurrentPage(currentPage);// 设置当前页
pb.setPageSize(pageSize);// 设置每页显示数据
int count = userDao.queryCount();// 获取总个数
pb.setTotalCount(count);// 设置总个数
List<Users> data = userDao.queryUsersByPage(currentPage, pageSize);
pb.setData(data);//设置分页数据
int pages=count%pageSize==0?(count/pageSize):(count/pageSize+1);
pb.setPages(pages);//设置总页数
return pb;// 给PageBean的每个属性设置值并返回
}
分页的控制器层编写
doGet(){
int currentPage = 1;// 设置默认当前页为第1页
int pageSize = 10;// 设置分页数据条数 (一般写死不变)
String currentPage2 = request.getParameter("currentPage");//获取网页发送的第几页请求数据
if (currentPage2 != null) {//判断数据是否为空
currentPage = Integer.parseInt(currentPage2);//将获得的网页页数数据设置为当前页
}
PageBean<Users> pb = userService.showUsersByPage(currentPage, pageSize);// 查询分页数据
request.setAttribute("pb", pb);//将查询到的分页数据设置为request域对象
request.getRequestDispatcher("userspage.jsp").forward(request, response);//重定向回网页
}
userspage.jsp编写(部分代码)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!-- 导入JSTL头文件 -->
<html>
<head>
<script type="text/javascript" src="项目名/static/js/jquery-1.11.0.min.js"></script>
</head>
<body>
<c:if test="${empty pb.data }">没有数据</c:if><!-- 判断是否获得数据 -->
<c:if test="${!(empty pb.data) }">
<table>
<caption>所有用户数据</caption>
<tr><th>UID</th><th>用户名</th><th>姓名</th><th>性别</th><th>生日</th><th>操作</th></tr>
<c:forEach items="${pb.data}" var="user"> <!-- 显示在网页的表格数据 -->
<tr>
<td>${user.uid}</td>
<td>${user.uname}</td>
<td>${user.name}</td>
<td>${user.gender}</td>
<td>${user.birthday}</td>
<td>
<a href="javascript:void(0)" οnclick="deleteUser(${user.uid})">删除</a>
<a href="项目名/updateUserView?uid=${user.uid}">修改</a>
</td>
</tr>
</c:forEach>
</table>
<!-- 首页、上一页、下一页、尾页、跳转的链接方法 -->
<!-- 当总页数为一页时 -->
<c:if test="${pb.pages==1}">
<span>当前页 1 共 1 页</span>
</c:if>
<!-- 当前页为第1页时,设置首页和上一页为空 -->
<c:if test="${pb.currentPage eq 1}">
<a href="javascript:void(0)">首页</a>
<a href="javascript:void(0)">上一页</a>
<a href="项目名/showAllUsersByPage?currentPage=${pb.currentPage+1}">下一页</a>
<a href="项目名/showAllUsersByPage?currentPage=${pb.pages}">尾页</a>
</c:if>
<!-- 当前页为中间页时,各链接的写法 -->
<c:if test="${pb.currentPage>1 && pb.currentPage<pb.pages}">
<a href="项目名/showAllUsersByPage">首页</a> <!-- 不传参数默认当前页为1 -->
<a href="项目名/showAllUsersByPage?currentPage=${pb.currentPage-1}">上一页</a>
<a href="项目名/showAllUsersByPage?currentPage=${pb.currentPage+1}">下一页</a>
<a href="项目名/showAllUsersByPage?currentPage=${pb.pages}">尾页</a>
</c:if>
<!-- 当前页为尾页时,设置下一页和尾页为空 -->
<c:if test="${pb.currentPage eq pb.pages}">
<a href="项目名/showAllUsersByPage">首页</a>
<a href="项目名/showAllUsersByPage?currentPage=${pb.currentPage-1}">上一页</a>
<a href="javascript:void(0)">下一页</a>
<a href="javascript:void(0)">尾页</a>
</c:if>
<!-- 页面跳转的写法 -->
<span>当前页${pb.currentPage}共${pb.pages}页</span>
<span>跳到<input type="text" style="width:20px" value="${pb.currentPage}" id="jump">页
<button οnclick="jump()">确定</button></span>
</c:if>
</body>
<script type="text/javascript">
function jump() {//跳转函数
var $pg = $("#jump").val();//获取第几页数据
if (!isNaN($pg) && $pg >= 1 && $pg <= $ {pb.pages}) {//判断是否为数字,数字是否在1到总页数之间
window.location.href = "项目名/showAllUsersByPage?currentPage=" + $pg;
} else {
$("#jump").val("");//清空内容
$("#jump").focus();//获得焦点
}
}
</script>
</html>