Java-Web

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的生命周期

  1. 实例化 构造方法

    默认情况下,当你第一次访问该servlet程序的时候 会去创建该servlet的对象,只创建。

  2. 初始化 init方法

    当初始化的时候 两个init()方法都会被调用, 有些时候我们可能会在servlet初始化的时候去写一些业务代码,这个时候我们的代码可以写在init方法里面。

    推荐把我们自己的代码写在无参的init方法里面。init方法只被执行一次

  3. service方法

    service方法 是servlet程序的主入口,每次访问servlet程序都会走他,他会调用具体的doGet和doPost方法,会被调用n次。

  4. 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&lt;request&lt;session&lt;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() 方法

. p o s t ( ) H T T P P O S T .post() 方法通过 HTTP 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>&nbsp;&nbsp;
<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>
发布了25 篇原创文章 · 获赞 1 · 访问量 1984

猜你喜欢

转载自blog.csdn.net/weixin_45631876/article/details/103319416