JavaEE

JavaWeb - J2EE - JavaEE

 

Http协议:超文本传输[服务器、客户端]协议

 

 

请求

请求行:请求提交方式[get/post]、请求的地址URI

请求头:请求的客户端信息  map

请求体:提交的请求参数 - post  [get提交参数,在URI中?]

响应

响应行:响应状态码

响应头:Map 服务器信息

响应体:响应内容[页面、JSON]

 

---------------------------------------------------------------------------

Tomcat:web应用服务器 - 软件   port:8080

web应用:动态网络资源

                 Java代码完成的可以在浏览器上运行的应用程序

                 部署在web应用服务器上的

tomcat编码:ISO8859-1

 

目录

Tomcat - apache   纯Java写   开源   免费

bin:命令、工具

          startup                bat sh

                    ./startup.sh

          shutdown

lib:类库 jar

          servlet-api

          jsp-api

conf:配置文件

          server.xml - 服务器配置

          web.xml - tomcat中所有的web应用,不能修改

webapps:web应用 多个

          目录/文件[html、css、js、.class、jar...]

work:工作目录

          jsp 翻译文件

temp:临时文件

          logs:日志

backup:备份

 

 

web应用与web工程对比

 

web应用:webapps里面的目录

根目录

      |- web静态资源

                 html\css\js\图片...

      |- WEB-INF - 目录是受保护的[客户端不能直接访问]

                   |- web.xml - 当前web应用配置信息

                                                   schame 约束

                  |- classes - 类路径 - src源码编译过来

                   |- lib - 库 jar[mysql、c3p0、dbutils]

      |- META-INF 元信息

 

web工程:eclipse 代码

src: 资源目录

          java代码、配置文件

JRE System Library:jdk 类库

Apache Tomcat v8.5:tomcat类库

build: 类路径 - 工程

          classes

          src源代码编译后的文件

WebContent/WebRoot:web应用根目录

          web静态资源

          META-INF

          WEB-INF

                    |- lib

                    |- web.xml - 服务器启动时就会读取

                       服务器启动完成后,检查控制台有没有报错

 

-----------------------------------------------------------------------------------------

Servlet三个规范:Servlet、Filter、Listener

web应用:

默认主页:index、default

 

JavaEE提供HTTP协议,web开发规范 Servlet JSP

Servlet:Server + applet

Servelt 规范用来接收请求,返回响应

 

 

实现Servlet步骤:

1.自定义类,实现Servlet接口

2.重写service方法

3.到web.xml文件中注册Servlet

<servlet>

          <servlet-name>自定义名字

        <servlet-class>完整类名

<servlet-mapping>

        <servlet-name>一致的名字

        <url-pattern>资源路径 /xx

4.访问测试:

http://localhost:8080/应用名/资源名        

http://localhost:8080/web01/a/hi

 

 

------------------------------------------------------------------------------------------------

Servlet生命周期:- 单例模式

  init: 对象创建时,初始化调用

 默认第一次接收请求创建

 可以修改为服务器开启时创建   <load-on-startup>n

  service:服务核心方法,用来接收请求。每一次请求接收时调用

  destroy:对象销毁,服务器关闭

 

 什么时候创建?

默认第一次接收请求时创建

可以设置为服务器开启时创建

          <load-on-startup>10</load-on-startup>

 什么时候销毁?

         服务器关闭销毁

 

----------------------------------------------------------------------------------------------

一共有23种设计模式

单例模式:

应用执行过程当中,只有一个对象的模式,叫做单例模式

懒汉模式、饿汉模式

工厂模式:简单工厂、抽象工厂、工厂方法

结合反射

spring

装饰者模式

代理模式:spring

 

 

单例模式线程不安全。(一般放方法,不放成员变量)

          整个应用运行过程中,只有一个对象生成

               Singleton s1 = Singleton.print();

          

          1.构造器私有

               private Singleton() {}

          2.提供可以获得对象的静态方法

               public static Singleton print() {}

          3.保证对象只new一次,将对象设置为static的

               private static Singleton single

          

          懒汉模式用的时候再创建(使用对象时,再创建对象)

private static Singleton single = null;

public static Singleton print() {

    synchronized (Singleton.class) {

        if (single == null) {

            single = new Singleton();

        }

    }

    return single;

}

 

          饿汉模式:加载时直接创建(类加载时,对象就已经创建好)

private static Singleton single = new Singleton();

public static Singleton print() {

    return single;

}

----------------------------------------------------------------------------------------------------------------------------

ServletConfig : Servlet相关配置,一个Servlet对应一个config

<!-- 初始化配置parameter -->

          <init-param>

                  <param-name>driver</param-name>

                  <param-value>com.mysql.jdbc.Driver</param-value>

          </init-param>

ServletConfig 作用:

// 作用一:获得Servlet对应的name

// <servlet-name>HelloKitty</servlet-name>

String servletName = config.getServletName();

// 作用二:获得Servlet自己的初始化配置信息

String driver = config.getInitParameter("driver");

// Enumeration<String> names = config.getInitParameterNames();

// 作用三:获得ServletContext对象

ServletContext context = config.getServletContext();

 

--------------------------------------------------------

HttpServlet 类 间接实现了 Servlet接口

实现了service方法,调用了自己的service方法

判断请求方式,调用 doGet/doPost

----------------------------------------------------

匹配

    <!-- 方式一:完全匹配 -->

    <!-- <url-pattern>/HelloServlet</url-pattern> -->

    <!-- 方式二:目录匹配 - Filter/SpringMVC -->

    <!-- http://localhost:8080/web02/hello/kitty.html -->

    <url-pattern>/hello/*</url-pattern>

    <!-- 方式三:后缀匹配 - 管理系统 -->

    <!-- <url-pattern>*.html</url-pattern> -->

 

结论:所有的资源都是由 Servlet 来处理的

 html jpg css js jsp .. .do  ..Servlet

 

 有一个默认的Servlet来接收web.xml中匹配不到的资源

 全局的web.xml中配置了缺省/默认的Servlet来接收其他请求

         DefaultServlet

         <servlet-mapping>

                    <servlet-name>default</servlet-name>

                    <url-pattern>/</url-pattern>

         </servlet-mapping>

-----------------------------------------------------------------------------------

ServletContext -> ApplicationContext

应用上下文:属于应用,一个应用只有一个上下文

创建:服务器开启

销毁:服务器关闭

 

1.获得ServletContext

       config.getServletContext()

2.request.getServletContext();

       小范围对象可以获得大范围对象的引用

3.servlet.getServletContext();

  <!-- 应用全局参数 -->

  <context-param>

          <param-name>location</param-name>

          <param-value>c3p0-config.xml</param-value>

  </context-param>

 

ServletContext 和 ServletContext域

域对象:存取数据使用        Map<String, Object>

   域范围:参考生命周期(服务器开始到结束)

   setAttribute(key, value)

   value getAttribute(key)

   removeAttribute(key);

 

ServletContext 作用:

ServletContext context = request.getServletContext();

// 作用一:获得应用名  /web02

// "/we02/hello" - 用path 替换/web02

String path = context.getContextPath();

// 作用二:获得应用的全局参数

String parameter = context.getInitParameter("location");

// 作用三:通过应用中资源的相对路径获得资源的绝对路径

// 1.src/a.txt

// 2.WebContent/b.txt

// 3.WEB-INF/c.txt

// 4.工程/d.txt - 不存在应用中

String a = context.getRealPath("WEB-INF/classes/a.txt");

String b = context.getRealPath("b.txt");

String c = context.getRealPath("WEB-INF/c.txt");

// 作用四:作用域对象

// 向域中存数据

context.setAttribute("name", "zhangsan");

// 从ServletContext域中数据

Object attribute = context.getAttribute("name");

// 从域中删除对应数据

context.removeAttribute("name");

-----------------------------------------------------------------------------

Response响应

 

// 1.响应行 - 状态码 200 404 304 302 500

response.setStatus(304);

int status = response.getStatus();

// 2.响应头 - Map<String, String>

  setHeader("location", "url")

  setIntHeader(name, value)

  setDateHeader(name, value)

// 如果原来有,覆盖掉值

response.setHeader("name", "lisi");

// 新增一个值,不论之前有没有

response.addHeader("name", "zhangsan");

// response.getHeader("name");

response.getWriter().write("hello Bonnie...");

//3.响应体

  getOutputStream(); // 文件复制/下载

  // 通知浏览器打开文件的方式 - 以附件形式

response.setHeader("Content-Disposition", "attachment;filename=" + filename);

  getWriter();

             write print println

  setCharacterEncoding(); // response缓冲区编码

  // meta

  setContentType("text/html;charset=utf-8");

 

 

// 302 -> 重定向:当前Servlet做完了,继续下一次任务,使用重定向

// response.setStatus(302);

// location:url地址

// response.setHeader("location", "/web02/Servlet1Demo");

// 重定向最终代码,路径:绝对路径,从应用名开始    "/应用名/资源名"

response.sendRedirect("/web02/Servlet1Demo");

 

// 注意:1.字节流字符流不能同时使用

//            2.通过response打开的流,不能手动关闭,tomcat会负责关闭

// OutputStream os = response.getOutputStream();

// 设置response缓冲区编码  ISO8859-1

// response.setCharacterEncoding("utf-8");

// 设置响应类型 - 方式、编码

response.setContentType("text/html;charset=utf-8");

PrintWriter writer = response.getWriter();

// 写到客户端 -> 页面

writer.println("哈哈");

 

----------------------------------------------------------------------------

Request请求:HttpServletRequest -> ServletRequest

行:uri method

             getMethod()

             getRequestURI()

             getRequestURL()

             getQueryString() -- 了解

             客户端IP地址

头:客户端信息 Map

        referer、user-agent

               getHeader("user-agent/referer") cookie

               getIntHeader()

               getDateHeader()

体:post参数

 

post: form method="post"

get: 直接访问、超链接、重定向、form method=“get”

 

获得请求参数 name=value  name:value

String  getParameter(name)

String[]  getParameterValues(name)

集合  getParameterNames()

Map<String, String[]>  getParameterMap()

-> BeanUtils.populate();

 

get/post 提交方式区别:

1.get参数在url上

  post参数在请求体中

2.get参数有大小限制

  post参数没有大小限制

3.get参数格式只能是字符串

  post支持多种类型 - 文件

4.编码

  get 和tomcat编码一致 - 可以改

  post ISO8859-1 - 不能改

Tomcat默认编码就是ISO8859-1

  和eclipse进行了绑定 - 通过eclipse 开启的服务器 utf8

  独立的tomcat单独启动 iso8859-1

 

 

// 1.获得request行信息 method    uri?get参数    GET/POST        

String method = request.getMethod();

// 2.URI/URL  post/get获得内容一样

String requestURI = request.getRequestURI();

String requestURL = request.getRequestURL().toString();

// 3.get提交方式的参数  - ?后面部分

// post方式得到的是null

String queryString = request.getQueryString();

 

// 1.获得request头信息  cookie referer

String agent = request.getHeader("user-agent");

// 获得客户端地址

String addr = request.getRemoteAddr();

// referer:资源来源 - 通过哪里访问的

String referer = request.getHeader("referer");// 防盗链

// 判断是自己服务器访问的该链接

if(referer == null || referer.startsWith("http://localhost:8080")) {

response.setContentType("text/html;charset=utf-8");  --> 服务器显示为utf-8编码

response.getWriter().write("新闻三:今年七夕没有520红包");

} else {

// 跳转到首页

response.sendRedirect("/web03/index.html");

}

 

 

// URI/URL ? 中文   解码 -> 编码 -> 通用

// name=%E7%AB%A0%E4%B8%89 -> 恢复

String queryString = request.getQueryString();

// URLEncoder.encode(queryString, "utf-8"); - 解码

queryString = URLDecoder.decode(queryString, "utf-8"); - 编码

// 请求设置编码

request.setCharacterEncoding("utf-8"); - post

 

// 设置响应类型为纯文本 或者 application/json

response.setContentType("text/plain;charset=utf-8");

 

// request可以直接获得应用名

// request.getServletContext().getContextPath();

request.getContextPath();

 

// 获得文件对应的mimetype类型

String mimeType = request.getServletContext().getMimeType("jpg");

 

// 接收请求参数

// 设置request 解析编码 - post有效

// request.setCharacterEncoding("UTF-8");

// 1.一个name对应一个value

// radio(单选)不选,获得null

// text/password/textarea/date  不填,获得""

 String name = request.getParameter("name");

// ---- 解决乱码  get编码设置为ISO8859-1

name = new String(name.getBytes("ISO8859-1"),"utf-8");

// 2.一个name对应多个value   [ check多选  select下拉列表 ]

String[] hobbies = request.getParameterValues("hobby");

// 3.

Map<String, String[]> parameterMap = request.getParameterMap();

 

 

request作为域对象使用

request域 - 一次请求

setAttribute

getAttribute

removeAttribute

 

-------------------------------------------------------------------

 

转发:通过reqeust

我们可以认为转发的过程是同一个请求和响应

共用同一个request 的 map域

但是,本质而言是不同的对象

结论:直接接收请求的资源才可以使用getParameterxx方法

// 同一次请求的跳转 -> 转发 forward

//RequestDispatcher dispatcher = request.getRequestDispatcher("");

//dispatcher.forward(request, response);

// 转发给Servlet2Demo - 应用内部转发,默认是当前同一个路径    "/资源名"

request.getRequestDispatcher("/Servlet2Demo").forward(request, response);

 

客户端路径:http://ip:port/appName/资源名

              /appName/资源名 - 在同一个服务器中

               href  src  action 都是客户端路径

服务器端路径转发, 应用内部转发

               默认是当前同一个应用

               /资源名 - 同一个应用中

 

-----------

封装对象

  -- 参数太多、属性太多,使用BeanUtils

BeanUtils.populate(user, request.getParameterMap());

  -- id是32位字符串,使用UUID

UUID.randomUUID().toString()

user.setUid(uid.replace("-", "")); - 去除四个 -,剩余32位。设置uid

 

---------------------------------------------------------------------------------------------

文件下载案例

// 获得请求参数 /web02/download/a.flv

String filename = request.getParameter("filename");

String name = null;

// 解决浏览器不支持中文的问题

// agent就是请求头中的user-agent

String agent = request.getHeader("user-agent");

if (agent.contains("MSIE") || agent.contains("TRIDENT") || agent.contains("EDGE")) {

// IE浏览器

name = URLEncoder.encode(filename, "utf-8");

name = name.replace("+", "%20");

} else if (agent.contains("Firefox")) {

// 火狐浏览器

BASE64Encoder base64Encoder = new BASE64Encoder();

name = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";

} else {

// 其它浏览器

name = URLEncoder.encode(filename, "utf-8");                                

}

// 告诉浏览器,文件是以附件形式打开,不是直接解析

response.setHeader("Content-Disposition", "attachment;filename=" + filename);

// 获得要下载文件的绝对路径

String path = request.getServletContext().getRealPath("download/" + filename);

// 打开输入流

InputStream in = new FileInputStream(path);

// 获得输出流

OutputStream out = response.getOutputStream();

// 复制

byte[] bs = new byte[1024];

int len = -1;

while((len = in.read(bs)) != -1) {

out.write(bs, 0, len);

}

in.close();

out.close();

 

-----------------------------------------------------------------------------------------------

 

编码问题:

 

 请求编码   Tomcat默认编码就是ISO8859-1

get 和tomcat编码一致 - 可以改

post ISO8859-1 - 不能改

// 设置response缓冲区编码  ISO8859-1

// response.setCharacterEncoding("utf-8");

// 设置响应类型 - 方式、编码

// response.setContentType("text/html;charset=utf-8");

// 设置响应类型为纯文本 或者 application/json

response.setContentType("text/plain;charset=utf-8");

// 设置request 解析编码 - post有效

// request.setCharacterEncoding("utf-8");

// ---- 解决乱码  get编码设置为ISO8859-1

name = new String(name.getBytes("ISO8859-1"),"utf-8");

 

--------------------------------------------------------------------------------------------------

代理主键、自然主键

id:

序列 sequence.nextVal

        自增长 auto_increment

        uuid

 

-----------------------------------------------------------------

会话

第一次请求发送过来,开始会话

多次请求

关闭客户端结束会话

 

HTTP协议无状态,客户端本身没有有效信息给服务器

 

-----------------------------------------------

Cookie存在客户端  -- 一次会话

1.服务器接收到请求

2.服务器通过response把内容存储在客户端

Cookie默认是会话结束就清除的

          可以设置Cookie的持久化

 

// 1.创建Cookie  map 不支持中文

Cookie cookie = new Cookie("name", "bao");

// 设置cookie的持久化时间,单位是秒

cookie.setMaxAge(Integer.MAX_VALUE);

// 携带路径;访问哪些资源会把cookie携带到服务器

// 默认携带路径 - 当前目录,不是当前应用

// /web4/Servlet3Demo

// cookie.setPath("/"); // -- 当前服务器中所有应用

cookie.setPath("/web04"); // -- 当前应用

// 2.Cookie带到客户端

response.addCookie(cookie);

// 结论:只有name和path一致的时候,才算同一个cookie

 

// 获得客户端通过request携带过来的Cookie

Cookie[] cookies = request.getCookies();

 

---------------------------------------------------------------------------------------------------------------

 

Session存在于服务器。存数据。取数据

域对象范围:一次会话

如果第一次调用,服务器会给客户端先创建一个session,返回

如果再次调用,直接返回原先创建好的session

 

Session什么时候创建

          第一次调用request.getSession()        

什么时候销毁

注意:不是会话结束session就销毁的!!

          服务器关闭(非正常关闭)

          手动销毁 session.invalidate()

          超时,默认30分钟 - 全局web.xml

                <session-config>

                                <session-timeout>1</session-timeout>

                       </session-config>

 

// 1.获得session对象。小范围获得大范围

HttpSession session = request.getSession();

// 2.存数据

session.setAttribute("age", 19);

String jsessionid = session.getId();

// 3.JSESSIONID持久化

Cookie cookie = new Cookie("JSESSIONID", jsessionid);

cookie.setPath(request.getContextPath());

cookie.setMaxAge(Integer.MAX_VALUE);

response.addCookie(cookie);

// 手动销毁

// session.invalidate();

// 获得Session中保存验证码

String checkcode_session = (String) request.getSession().getAttribute("checkcode_session");

 

 

------------------------------------------

小结:域范围从大到小

ServletContext:服务器应用

session:一次会话 - 登录后的用户信息、购物车

request:一次请求 - 转发

cookie:存客户端、JSESSIONID、用户名、密码

 

 

---------------------------------------------------------------------------------------------------------

 

JSP:Java Server Page

JSP可以接收请求、返回响应,本质就是Servlet

 

JSP - 工作文件 tomcat -> work

原理:JSP运行之前,在第一次访问JSP文件时翻译成java代码

                    xx.jsp -> xx_jsp.java

                    间接继承HttpServlet,JSP本质就是Servlet

 

<html> --> out.write()

<%  %> --> 翻译后,出现在service方法中

<%= %> --> out.print()

<%! %> --> 会被翻译成servlet的成员的内容

 

jsp注释可见范围:JSP代码、翻译后的Java代码、、html页面源码

<!-- -->  html注释  :JSP代码、翻译后的Java代码、html页面源码

// java注释              :JSP代码、翻译后的Java代码

<%-- --%> jsp注释 :JSP代码

 

-----------------------------

JSP:

html标签

css

js

3种java脚本

3种注释

<%@ %> JSP指令

JSP内置对象

JSP动态标签

EL表达式

JSTL标签

---

<%@ %> JSP指令

page:属性最多

          language:java、php、c#

          contentType:response.setContentType(text/html;charset=UTF-8);

          pageEncoding:包含了contentType 当前页面编码

          extends:继承

          session:默认true,false-不能在jsp中使用session

          errorpage:出现异常后,转发到的页面

          isErrorPage:默认false

          isELIgnored:默认false,el有效

          import:导包

 

include:包含子页面 - 静态包含

          格式:<%@ include file="被包含的文件地址"%>

          file:页面路径

taglib:引入标签库

          格式:<%@ taglib uri="标签库地址" prefix="前缀"%>

          uri:库的资源路径

          prefix:前缀

 

JSP内置对象:在JSP脚本中可以直接使用的对象 9个

HttpServletRequest request

HttpServletResponse response

ServletContext application

HttpSession session

PageContext pageContext

Writer out

ServletConfig config

page -> this xx_jsp.Servlet

exception -> 抓取到的异常 isErrorPage = "true"

 

out: 输出流 缓冲区

           buffer = "0kb" - 关闭out缓冲区,内容直接写到respons缓冲器

pageContext:域对象 - 当前页面

          可以操作其他三个域

                    pageContext.setAttribute("name", "zhangsan", PageContext.APPLICATION_SCOPE);

                    pageContext.getAttribute("name", PageContext.APPLICATION_SCOPE)

          findAttribute(name)

                    pageContext.findAttribute("name")

                    -- 依次从pageContext域,request域,session域,application域四个域中,寻找name对应的值,直到找到为止

                    -- 从小到大

          四大作用域的总结:

                    page域:当前JSP页面范围

                    request域:一次请求

                    session域:一次会话

                    application域:整个web应用

          可以获得其他8大隐式对象

                    pageContext.getRequest()

                    pageContext.getSession()

 

 

JSP动态标签

         <!-- 动态包含 -->

          <jsp:include page="jsp1.jsp"></jsp:include>

 

<!-- 转发 -->

          <jsp:forward page="/pageContext1.jsp"></jsp:forward>

 

静态包含和动态包含的区别?

静态包含:<%@include file=""%>

          翻译出一个java文件,编译,运行

动态包含:<jsp:include page="">

          翻译出两个java文件,编译,运行

 

EL表达式:Expression Language

目的:为了从域中获得数据

           取代get方法 - 减少Java脚本

语法:${表达式 }

内置对象:11个 -- 了解

 

<!-- applicationScope/sessionScope/requestScope/pageScope -->

<!-- 取代四个域中的getAttribute(name) -->

applicationScope ---- ${applicationScope.name }<br>

sessionScope ---- ${sessionScope.age }<br>

requestScope ---- ${requestScope.name }<br>

pageScope ---- ${pageScope.name }<br>

 

<!-- pageContext.findAttribute(name) -->

${name } ---- 最常用用法

 

${1+1 } -> 打印 2

 

${list == null ? 1:2 }

 

<!-- 为空=true,不为空=false

           null 一定是空,  ""/空集合 -> true

           判断依据,值是不是有效值,内容是否为空

 -->

${empty list }

 

<!-- EL内置对象 -->

<!-- pageScope/requestScope/sessionScope/applicationScope -->

<%-- request.getParameter("username") --%>

${param.username } <br>

<%-- request.getParameterValues("username") --%>

${paramValues.username[1] }<br>

<!-- request.getHeader("user-agent") -->

user-agent: ${header['user-agent'] }<br>

Host: <%-- ${header.host } --%> ${header['host'] }<br>

initParam: ${initParam.aaa }<br>

<!-- cookie 相当于 Map<name, Cookie> -->

${cookie.JSESSIONID.value}<br>

${pageContext.request.contextPath } /web05

 

例:

          <%

                    // EL获得Map<String,User>的值

                    Map<String, User> userMap = new HashMap<String, User>();

                    User u1 = new User("lucy", 18);

                    User u2 = new User("tom", 20);

                    User u3 = new User("jack", 25);

                    User u4 = new User("marry", 30);

                    User u5 = new User("john", 33);

                    userMap.put("u1", u1);

                    userMap.put("u2", u2);

                    userMap.put("u3", u3);

                    userMap.put("u4", u4);

                    userMap.put("u5", u5);

                    request.setAttribute("userMap", userMap);



                    // EL获得Map<String, List<User>>的值

                    Map<String, List<User>> listMap = new HashMap<String, List<User>>();

                    List<User> userList1 = new ArrayList<User>();

                    userList1.add(u1);

                    userList1.add(u2);

                    userList1.add(u3);

                    userList1.add(u4);

                    List<User> userList2 = new ArrayList<User>();

                    userList2.add(u1);

                    userList2.add(u2);

                    userList2.add(u3);

                    userList2.add(u4);

                    List<User> userList3 = new ArrayList<User>();

                    userList3.add(u1);

                    userList3.add(u2);

                    userList3.add(u3);

                    userList3.add(u4);

                    listMap.put("userList1", userList1);

                    listMap.put("userList2", userList2);

                    listMap.put("userList3", userList3);

                    request.setAttribute("listMap", listMap);

          %>

<!-- EL表达式 . 出来的是什么类型 -->

${userMap.u3.name } -- ${userMap.u3.age }

${listMap.userList2[3].name } -- ${listMap.userList2[3].age }

 

JSTL标签

<!-- JSTL标签库使用

          1.导库    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

          12.使用,添加前缀

          13.配合EL表达式使用

 -->

------------------------

 <!-- if(a==1)   if判断

         test:判断条件

  -->

 <c:if test="${user == null }">

         <a href="#">请登录</a>

 </c:if>

 <c:if test="${!empty user }">

         ${user.name }

 </c:if>

----------------------------------------------------------------------

 <!-- for(int i = 0; i < 10; i++) {}    for循环

 var="i" -> 等同于在当前页面定义了一个变量i,并且存入page域中

  -->

 <c:forEach begin="0" end="9" step="1" var="i">

         ${i }

 </c:forEach>

-------------------------------------------------------------------------------------------------

<!--  for(String str : list) {} -->   遍历List<String>的值

 <!-- 等同于,从List中依次迭代元素,取名叫str,存入page域中 -->

 <c:forEach items="${list }" var="str">

         ${str }

 </c:forEach>

----------------------------------------------------------------------------------------------------------------

 <c:forEach items="${userList1 }" var="user">    遍历List<User>的值

         ${user }<br>

 </c:forEach>

--------------------------------------------------------------------------------------------

 <!-- entrySet entry:键值对 -->

 <c:forEach items="${strMap }" var="entry">     遍历Map<String,String>的值

         ${entry.key } ---- ${entry.value }<br>

 </c:forEach>

-----------------------------------------------------------------

 <!-- entrySet entry:键值对 -->

 <c:forEach items="${userMap }" var="entey">     遍历Map<String,User>的值

         ${entey.key } ---- ${entey.value }<br>

 </c:forEach>

 

 

-----------------------------------------------------------------------------------------------------------------

 javaEE的开发模式

 

model1: JSP + javaBean        

model2: Servlet + jsp + javaBean

Servlet:擅长写Java代码

JSP:擅长页面

 

MVC模式:

M:model----模型 javaBean:封装数据

V:view----视图 JSP:单纯进行页面的显示

C:controller----控制器 Servlet:获取数据--对数据进行封装--传递数据--指派显示的jsp页面

 

JavaEE三层架构

web:前端交互 servlet +  jsp +  javabean

service:业务处理

dao:数据库操作 -> dbutils   c3p0  jdbc

 

----------------------------------------------------------------------------------------------------------------------------------------

 

Filter 过滤器:在Servlet之前进行的拦截/过滤

过滤、拦截请求

url-pattern

 

实现过滤器

1.自定义类实现Filter接口

2.着重实现doFilter方法

3.注册 - 参考servlet

  <filter>

           <filter-name>MyFilter1</filter-name>

           <filter-class>a_filter.MyFilter1</filter-class>

           <init-param>

                      <param-name>name</param-name>

                      <param-value>lucy</param-value>

           </init-param>

  </filter>

<filter-mapping>

          <filter-name>MyFilter</filter-name>

          <!-- 进入哪些路径之前进行过滤 -->

          <url-pattern>/*</url-pattern>

</filter-mapping>

 

过滤器中可以有响应内容,也可以不放行

放行后的响应内容也生效

 

多个过滤器,顺序由filter-mapping的注册顺序决定 - chain

chain.doFilter(); - 递归

每一个过滤器都要放行,才能进入Servlet资源

 

没有放行意味着拦截了,放行意味着去了真正想访问的资源    -- chain.doFilter(request, response);

 

配置文件详解

  <filter-mapping>

          <filter-name>MyFilter2</filter-name>

          <!-- 等同于url-pattern,只能精确匹配,可以和url-pattern同时使用 -->

          <!-- <servlet-name>Servlet1Demo</servlet-name> -->

          <!-- 方式一:精确匹配 -->

          <url-pattern>/Servlet1Demo</url-pattern>

          <!-- 方式二:目录匹配 -->

          <!-- <url-pattern>/hello/*</url-pattern> -->

          <!-- 方式三:后缀匹配 -->

          <!-- <url-pattern>*.jsp</url-pattern> -->

          <!-- 拦截请求方式

                   REQUEST:直接访问,超链接、重定向 - 默认

                   FORWARD:转发时

                   ERROR:errorPage="error.jsp"

                   INCLUDE:包含

                   可以多个选项共存

           -->

          <dispatcher>REQUEST</dispatcher>

          <dispatcher>FORWARD</dispatcher>

  </filter-mapping>

 

-------------------------

 

创建、销毁时间

ServletContext: 服务器开启、关闭

Servlet: 默认第一次接收请求、服务器关闭

Session: 第一次getSession()、3种方式

Request、Response: 一次请求

Filter: 服务器开启、关闭

--------------------------------------------

 

ServletConfig:

1.获得servlet-name

2.获得初始化init-param

3.获得ServletContext

FilterConfig

1.获得filter-name

2.获得初始化init-param

3.获得ServletContext

 

 

Filter功能:公共代码提取

-- 解决请求参数乱码:post get

           让Servlet专注于获得参数即可

                      getParameter(name);

 

-------------------------------

 

代码:解决请求参数乱码  -- 装饰者模式

HttpServletRequest request  -- 被装饰对象

MyRequest   -- 装饰对象

// 应该重写ServletResquest接口

// j2ee,提供了一个从来重写Request的类

 

class MyRequest extends HttpServletRequestWrapper{

// 使用被装饰对象来包装

private HttpServletRequest request;

// 重写getParameter方法

public MyRequest(HttpServletRequest request) {

           super(request);

           this.request = request;

}

@Override

public String getParameter(String name) {

           // 1.获得乱码

           String parameter = request.getParameter(name);

           // 2.解决乱码

           try {

                      parameter = new String(parameter.getBytes("ISO8859-1"), "utf-8");

           } catch (UnsupportedEncodingException e) {

                      e.printStackTrace();

           }

           // 返回中文

           return parameter;

}

}

 

将对象方法增强 - 装饰者模式:目的-为了增强对象的功能

被装饰对象(原始对象)、装饰对象(功能增强后的对象)

1.装饰对象拥有被装饰对象相同的父接口

2.重写要增强的方法

3.使用被装饰对象包装一个新对象  - 构造器

 

-----------------------------------------------------------------------------------------

 

Listener监听器:用或者不用,不影响动作的发生

作用:可以知道某个动作发生,并且做出对应的响应

种类:6 + 2 -> 接口

6: 3种域对象有关 request、session、application

2: 对象感知监听器,对象和session的关系

 

步骤

1.自定义类,实现xxxListener接口

2.注册

<listener>

               <listener-class>c_listener.MyServletContextListener</listener-class>

        </listener>

 

 

监听三大域对象的创建与销毁的监听器:request、session、application    3

例:

ServletContextListener:创建-服务器启动,销毁-服务器关闭;等同于监视服务器开启、关闭

           作用

                      1.初始化的配置、参数加载 -> Spring

                      2.任务调度

           contextInitialized:ServletContext创建时调用

           contextDestroyed:ServletContext销毁时调用

           任务调度:contextInitialized中

                      Timer timer = new Timer();

                      // 3000 -> 过3000毫秒,程序正式启动

                      // 10000 -> 周期性时间,1天

                      timer.schedule(new TimerTask() {

                                 public void run() {

                                            System.out.println("又过生日了!");

                                 }

                      }, 3000, 10000);

 

 

监听三大域对象的属性变化的监听器:request、session、application        3

例:

ServletContextAttributeListener

           内容改变:setAttribute();        removeAttribute();

           attributeAdded(ServletContextAttributeEvent scae)

                      可以获得被监听的对象;可以获得改变的属性内容,添加的属性name-value

           attributeRemoved(ServletContextAttributeEvent scae)

           attributeReplaced(ServletContextAttributeEvent scae)

                      再一次name,setAttribute(),scae.getValue()返回的是改变前的内容

 

--------------------------

对象感知监听器,对象和session的关系

1.绑定、解绑    HttpSessionBindingListener     valueBound - 绑定    valueUnbound - 解绑

2.钝化、活化    HttpSessionActivationListener     sessionWillPassivate - 钝化     sessionDidActivate - 活化

 

步骤:对象的实体类实现xxListener接口

 

session中的绑定的对象相关的监听器(对象感知监听器)        2

绑定与解绑的监听器HttpSessionBindingListener

钝化与活化的监听器HttpSessionActivationListener

钝化: Session存在服务器      sessionWillPassivate(HttpSessionEvent se)     

           服务器关闭后,session中保存的内容还在 - 服务器本地硬盘

           服务器关闭后,session对象在不在?- 内存中对象不在

           钝化:session数据Object -> 序列化 -> 硬盘字节    Serializable

           设定Session钝化时间,规定session多久不用,数据保存在硬盘,节省内存空间 -> 服务器优化

                      可以通过配置文件 指定对象钝化时间 --- 对象多长时间不用被钝化

                      <Context>

                                 <!-- maxIdleSwap:session中的对象多长时间不使用就钝化,单位为分钟 -->

                                 <!-- directory:钝化后的对象的文件写到磁盘的哪个目录下,配置钝化的对象文件在

                                                                                                                  work/catalina/localhost/钝化文件 -->

                                 <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">

                                                  <Store className="org.apache.catalina.session.FileStore" directory="bonnie" />

                                 </Manager>

                      </Context>

 

活化: 服务器重新开启     sessionDidActivate(HttpSessionEvent se)

本地硬盘中的session数据重新恢复到内存的过程

 

 

-------------------------------------------------------------------------------------------------------------------

 

Ajax

 

JS原生的Ajax技术

$("#btn0").click(function(){

           // 1.创建引擎对象

           var xmlhttp = new XMLHttpRequest();

           // 2.绑定监听

           xmlhttp.onreadystatechange = function(){

                      // 5.接收响应数据

                      if(xmlhttp.readyState==4 && xmlhttp.status==200){

                                 alert(xmlhttp.responseText);

                                 $("#span").html(xmlhttp.responseText);

                      }

           }

           // 3.绑定地址

           xmlhttp.open("GET", "/web08/Servlet1Demo", true);

           // 4.发送请求

           xmlhttp.send();

});

 

 JQuery的Ajax技术    3

  1. $.get(url, [data], [callback], [type])
  2. $.post(url, [data], [callback], [type])

 

url:代表请求的服务器端地址

data:代表请求服务器端的数据(可以是key=value形式也可以是JSON格式)

callback:表示服务器端成功响应所触发的函数(只有正常成功返回才执行)

type:表示服务器端返回的数据类型(JQuery会根据指定的类型自动类型转换);常用的返回类型:text、json、html等。

 

getpost代码相同

$("#btn2").click(function(){

           // 局部刷新\提交请求 - ajax

           $.get(

                      "/web08/Servlet1Demo",  // url

                      // "name=zhangsan&age=18&gendar=f",

                      // 请求参数提交  可以name=value,也可以json

                      {

                                 "name": $("#name").val(),

                                 "age": 19,

                                 "gendar": 'f'

                      },

                      function(data){ // 响应成功的回调函数,data - 相应内容

                                 $("#span").html(data.gendar);

                      },

                      // "text"  // 响应类型 text/json

                      "json"

           );

});

3.$.ajax( { option1:value1,option2:value2... } ); 最底层的方法

 

async:是否异步,默认是true代表异步

data:发送到服务器的参数,建议使用JSON格式

dataType:服务器端返回的数据类型,常用text和JSON

success:成功响应执行的函数,对应的类型是function类型

type:请求方式,POST/GET     ajax建议使用GET

url:请求服务器端地址

error:失败的回调函数,对应的类型是function类型

 

$("#btn1").click(function(){

           $.ajax({

                      url: "/web08/Servlet1Demo",

                      data: {

                                 "name": $("#name").val()

                      }, // 请求参数

                      success: function(data){

                                 $("#span").html(data.age);

                      },

                      dataType: "json",

                      type: "GET", // 默认get

                      async: false // 默认异步true,false - 同步

           });

});

 

自定义校验规则

<script type="text/javascript">

$(function(){

// 自定义校验规则

$.validator.addMethod("checkUser", function(value, element, params){

           var pass = false;

           // value:输入内容,需要给数据库对比

           $.ajax({

                      url: "/web08/CheckUserServlet",

                      data: {

                                 "username": value

                      },

                      success: function(data){

                                 // data.isExists -> true -> 校验不通过

                                 // data.isExists -> false -> 校验通过

                                 pass = !data.isExists;

                      },

                      dataType: "json",

                      async: false // 必须同步

           });

           return pass; // 返回true表示校验通过

});

// 信息校验

$("#regForm").validate({

           rules: {

                      username: {

                                 required : true,

                                 minlength : 6,

                                 maxlength : 20,

                                 checkUser : true

                      },

                      password: {

                                 required : true,

                                 minlength : 6,

                                 maxlength : 20                                        

                      }

           },

           messages: {

                      username: {

                                 required : "用户名不能为空",

                                 minlength : "用户名长度不能小于6",

                                 maxlength : "用户名长度不能大于20",

                                 checkUser : "用户名已存在"

                      },

                      password: {

                                 required : "密码不能为空",

                                 minlength : "密码长度不能小于6",

                                 maxlength : "密码长度不能大于20"                                        

                      }                                        

           }

 });

 });

</script>

 

java对象,变为json对象格式的字符串

List<Product> list = ps.SearchAllProduct(pname);

Gson gson = new Gson();

String json = gson.toJson(list);

 

 

--------------------------------------------------------------------------------------------------

类加载器3种

源代码 -> 编译 -> .class -> 加载 -> 方法区

 

类加载器加载类按顺序加载,相同类不能重复加载。(双亲委派机制

引导类加载器 - 加载都是最基础的文件

扩展类加载器 - 加载都是基础的文件

应用类加载器 - 三方jar包和自己编写java文件

 

 

类加载方式

           1.使用的时候

           2.ProductDao.class

           3.Class.forName("java.lang.String");

 

每一个类加载,都会得到一个它对应的Class对象

操作字节码对象 -> 反射 Class

 

类中所有的成员[属性、方法、父类、接口、异常...] 都可以通过字节码对象获得

 

反射理论中,基本数据类型和引用类型完全不同   int Integer 不同

 

反射

反射操作的是字节码对象 java.lang.String

 

代码1

//  String.class;

//  "hello".getClass();

//  Class.forName("java.lang.String");

 

Class cla = String.class;

// 调用对象的属性,方法

// 1.创建对象 - 构造器

// new String("haha")

String str = (String) cla.newInstance(); // 无参构造器

// 调用

System.out.println(str);

----------------------------------------------------------

代码2

Class clz = Class.forName("a_reflect.User");

// 默认就是使用可以访问的无参构造器

// User user = (User) clz.newInstance();

// System.out.println(user);

 

// 如果需要使用其他构造器

Constructor constructor = clz.getConstructor(int.class);

// 使用构造器

User u1 = (User) constructor.newInstance(34);

System.out.println(u1);

 

// 可以获得所有声明的构造器,包括私有的

Constructor c2 = clz.getDeclaredConstructor();

// 设置私有可见

c2.setAccessible(true);

User u2 = (User) c2.newInstance();

System.out.println(u2);

----------------------------------------------------------------------------

代码3

// 通过反射调用User对象的方法

Class clz = User.class;

// 调用传2个参数的有参构造器

Constructor constructor = clz.getConstructor(int.class, String.class);

User u = (User) constructor.newInstance(23, "lucy");

// User u = new User(23, "lucy");

// 1.获得User对象的方法    方法名为study,参数为String

Method method = clz.getMethod("study", String.class);

// 2.调用方法,并且获得返回值    u为对象,“java”为传的参数

String ret = (String) method.invoke(u, "java");

System.out.println(ret);

 

-------------------------------------------------------------------------------------------------

工厂模式:简单工厂、抽象工厂、工厂方法

-- 提供方法,为了获得对应的对象

配置文件 - key-value

           String - 类名 - 反射

           获得对应的对象

 

FactoryUtils

public class FactoryUtils {

    private static Properties pros;

    static{

        pros = new Properties();

        try {

        pros.load(new FileInputStream(FactoryUtils.class.getResource("Factory.properties").getFile()));

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    public static Object getInstance(String classKey) {

        // 1.通过key,获得对应的类名

        String className = pros.getProperty(classKey);

        // 2.获得对应的Class对象

        try {

            Class<?> clz = Class.forName(className);

            // 3.创建对象,并返回

            return clz.newInstance();

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        } catch (InstantiationException e) {

            e.printStackTrace();

        } catch (IllegalAccessException e) {

            e.printStackTrace();

        }

        return null;

    }

}

 

Factory.properties:

ProductDao = dao.impl.ProductDaoImpl

 

使用工厂模式:

ProductDao pd = (ProductDao) FactoryUtils.getInstance("ProductDao");

 

 

--------------------------------------------------------------------

注解     Annotation

 

注解作用:取代配置文件 Spring

注释:在阅读程序时清楚----给程序员看的,JVM自动跳过

注解:给jvm看的,给机器看的,JVM可以识别

 

JDK1.5三个注解

@Override:告知编译器此方法是覆盖父类的。只能放方法上,没属性

@SuppressWarnings:压制警告,被修饰的类或方法如果存在编译警告,将被编译器忽略。可放在类、成员变量、方法、局部变量上。属性类型 String[]

          deprecation,忽略过时

          rawtypes,忽略类型安全

          unused,忽略不使用

          unchecked,忽略安全检查

          null,忽略空指针

          all,忽略所有

@Deprecated:标注过时。放在任何位置,没属性

 

元注解JDK 2个 - 标注注解的注解。作用:限制定义的注解的特性

@Target    注解添加位置可以设置:类、属性、方法、构造器。。。。

          FIELD :  字段上可用此注解

          METHOD :  方法上可以用此注解

          TYPE :  /接口上可以使用此注解

@Retention    注解可见范围: 源码、字节码、运行时

          SOURCE :  注解在源码级别可见

          CLASS :注解在字节码文件级别可见

          RUNTIME :注解在整个运行阶段都可见

注解属性

规定有且只有一个必须有值的属性名为value时,属性名才可以省略

例:

          public @interface MyAnnotation{

                    int value();

                    // 属性可以有默认值

                    String name() default "haha";

          }

          可以写为  @MyAnnotation(10)

 

 

---------------------------------------------------------------------------------------------

 

分页查询

public PageBean<Emp> findEmpPageBean(String currentPageStr, String pageSizeStr) {

    int currentPage = 0;

    int pageSize = 0;
    
    if (currentPageStr == null) {

        currentPage = 1;

    } else {

        currentPage = Integer.valueOf(currentPageStr);

    }



    if (pageSizeStr == null) {

        pageSize = 3;

    } else {

        pageSize = Integer.valueOf(pageSizeStr);

    }

    int totalCount = ed.getCount();

    List<Emp> list = ed.findEmpByPage(currentPage, pageSize);



    PageBean<Emp> pb = new PageBean<Emp>(totalCount, currentPage, pageSize);

    pb.setList(list);

    return pb;

}



public int getCount() {

    String sql = "select count(1) from emp";

    try {

        long count = (Long) qu.query(sql, new ScalarHandler());

        return (int)count;

    } catch (SQLException e) {

        e.printStackTrace();

    }

    return 0;

}







public List<Emp> findEmpByPage(int currentPage, int pageSize) {

    // 第一个?:从第几条开始 0

    // 第二个?: pageSize

    // currentPage = 3,pageSize=2

    String sql = "select * from emp limit ?,?";

    int startRow = (currentPage-1) * pageSize;

    try {

        return qu.query(sql, new BeanListHandler<Emp>(Emp.class), startRow, pageSize);

    } catch (SQLException e) {

        e.printStackTrace();

    }

    return null;

}

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值