javaweb(全) 笔记

软件体系结构

c/s 架构

client (客户端) 服务器 架构

​ 需要编写服务器端程序,以及客户端程序,例如我们安装的就是QQ的客户端程序;

​ 缺点:软件更新时需要同时更新客户端和服务器端两端,比较麻烦;

​ 优点:安全性比较好。

b/s架构

browser(浏览器) 服务器架构

​ 只用编写服务端程序,但安全性较差;

  • URL

    • 格式:协议://服务器IP:端⼝/路径1/路径N ? key1=value1 & key2=value2

      • 协议:不同的协议有不同的解析⽅式,http 超文本传输协议, https 对http的加密,更安全,但解析时间会延长;
      • 路径:资源路径,例如 index.html ;
    • http 常见的请求方法:

      • http1.0 定义了3种
      • GET: 向服务器获取资源,⽐如常⻅的查询请求
        • 请求参数会在浏览器的地址栏中显示,所以不安全;
        • 请求参数长度限制长度在1K之内;
        • GET请求没有请求体,无法通过request.setCharacterEncoding()来设置参数的编码;
      • POST: 向服务器提交数据⽽发送的请求
        • 请求参数在请求头中,不会显示浏览器的地址栏,相对安全;
        • 请求参数长度没有限制;
      • Head: 和get类似,返回的响应中没有具体的内容,⽤于获取报头
      • http1.1 定义了6种方法
      • PUT:⼀般是⽤于更新请求,⽐如更新个⼈信息、商品信息全量更新
      • PATCH:PUT ⽅法的补充,更新指定资源的部分数据
      • DELETE:⽤于删除指定的资源
      • OPTIONS: 获取服务器⽀持的HTTP请求⽅法,服务器性能、跨域检查等
      • CONNECT: ⽅法的作⽤就是把服务器作为跳板,让服务器代替⽤户去访问其它⽹⻚,之后把 数据原原本本的返回给⽤户,⽹⻚开发基本不⽤这个⽅法,如果是http代理就会使⽤这个让服务器代理⽤户去访问其他⽹⻚,类似中介
      • TRACE:回显服务器收到的请求,主要⽤于测试或诊断

      http 常见状态码

      • 1xx :收到请求,需要请求者继续执⾏操作,⽐较少⽤

      • 2XX: 请求成功,常⽤的 200

      • 3XX: 重定向,浏览器在拿到服务器返回的这个状态码后会⾃动跳转到⼀个新的URL地址,这 个地址可以从响应的Location⾸部中获取;

        • 301:永久性跳转,⽐如域名过期,换个域名 302:临时性跳转
      • 4XX: 客服端出错,请求包含语法错误或者⽆法完成请求 ,

        • 400: 请求出错,⽐如语法协议 403: 没权限访问 404: 找不到这个路径对应

      的接⼝或者⽂件 405: 不允许此⽅法进⾏提交,Method not allowed,⽐如接⼝⼀定要

      POST⽅式,⽽你是⽤了GET

      • 5XX: 服务端出错,服务器在处理请求的过程中发⽣了错误

        • 500: 服务器内部报错了,完成不了这次请求 503: 服务器宕机

Servlet

Servlet 是 javaweb 三大组件(Servlet , Filter , Lisenter)之一 ;

作用:处理请求

  • 接收请求数据
  • 处理请求
  • 完场响应

servlet 实现

三种方式:

  • 实现javax.servlet.Servlet接口;
  • 继承javax.servlet.GenericServlet类;
  • 继承javax.servlet.http.HttpServlet类;

Servlet -->GenericServlet–>HttpServlet 继承关系; HttpServlet 常用

Servlet中的方法大多数不由我们来调用,而是由Tomcat来调用。并且Servlet的对象也不由我们来创建,由Tomcat来创建!

创建servlet

package servletDemo01;

import javax.servlet.*;
import java.io.IOException;

public class ServletImpl implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {

}

@Override
public ServletConfig getServletConfig() {
  return null;
}

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  
  System.out.println("servlet !!!");
}

@Override
public String getServletInfo() {
  return null;
}

@Override
public void destroy() {

}
}

配置 web.xml 文件,绑定url

<servlet>
  <servlet-name>ServletImpl</servlet-name>
  <servlet-class>servletDemo01.ServletImpl</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ServletImpl</servlet-name>
  <url-pattern>/ServletImpl</url-pattern>
</servlet-mapping>
  • servlet,servlet-mapping 的servlet-name : 必须一样,先是url访问tomcat ,通过name找到绑定的servlet-class,运行class文件,运行servlet ,处理请求;
  • 配置文件可以用 注解 @WebServlet(" / asd") 代替;放在我们的实现类上面,servlet-name 不重要,所以注解中提供了默认名称 “” 空字符串;我们只用配置url ;
  • url 通配符:
  • 表示所有; @WebServlet(".do") 表示以do 结尾的路径都可;

Servlet 生命周期

init( ); 出生 ;第一次访问时创建servlet,也可以在服务器启动时创建,此时需要额外配置 web.xml 文件,生命 周期中只会被调用一次;

​ 这里的 xml 额外配置:

​ xml 文件 : servlet 标签中 添加0 ,非负整数即可; 数字越小表示,在服务器启动时,Servlet越先创建;

​ 注解方式:@WebServlet(value = “/*”,loadOnStartup = 1) loadOnStartup 设置参数即可;

service( ); 处理请求

destroy( ) 销毁 服务器关闭时销毁;

  • Servlet 线程安全吗? 不安全
  • 当servlet 被创建后,不会立即销毁,当多个线程访问时,会进入到同一个servlet中,此时就容易造成线程不安全的相关问题
  • 一个Servlet能绑定多个 url 吗?
  • 可以,注解 @WebServlet({“”,“”}) 中可以是数组形式;

Servlet 相关接口

ServletRequest

HttpServletRequest 在ServletRequest 的基础上 增加了 http方法

方法:

  • String getParameter(String paramName):获取指定请求参数的值;
  • String getMethod():获取请求方法,例如GET或POST;
  • String getHeader(String name):获取指定请求头的值;
  • void setCharacterEncoding(String encoding):设置请求体的编码!因为GET请求没有请求体,所以这个方法只只对POST请求有效。当调用request.setCharacterEncoding(“utf-8”)之后,再通过getParameter()方法获取参数值时,那么参数值都已经通过了转码,即转换成了UTF-8编码。所以,这个方法必须在调用getParameter()方法之前调用!
ServletResponse

HttpServletResponse 在ServletResponse 的基础上 增加了 http方法

方法:

  • PrintWriter getWriter():获取字符响应流,使用该流可以向客户端输出响应信息。
  • ServletOutputStream getOutputStream():获取字节响应流,当需要向客户端响应字节数据时,需要使用这个流,例如要向客户端响应图片;
  • void setCharacterEncoding(String encoding):用来设置字符响应流的编码,例如在调用setCharacterEncoding(“utf-8”);之后,再response.getWriter()获取字符响应流对象,这时的响应流的编码为utf-8,使用response.getWriter()输出的中文都会转换成utf-8编码后发送给客户端;
  • void setHeader(String name, String value):向客户端添加响应头信息,例如setHeader(“Refresh”, “3;url=http://www.baidu.com”),表示3秒后自动刷新到http://www.baidu.com;
  • void setContentType(String contentType):该方法是setHeader(“content-type”, “xxx”)的简便方法,即用来添加名为content-type响应头的方法。content-type响应头用来设置响应数据的MIME类型,例如要向客户端响应jpg的图片,那么可以setContentType(“image/jepg”),如果响应数据为文本类型,那么还要台同时设置编码,例如setContentType(“text/html;chartset=utf-8”)表示响应数据类型为文本类型中的html类型,并且该方法会调用setCharacterEncoding(“utf-8”)方法;
  • void sendError(int code, String errorMsg):向客户端发送状态码,以及错误消息。例如给客户端发送404:response(404, “您要查找的资源不存在!”)。
ServletConfig

init()方法的参数,它表示Servlet配置对象,它对应Servlet的配置信息,那对应web.xml文件中的<servlet>元素。ServletConfig对象是由服务器创建的,然后传递给Servlet的init()方法,你可以在init()方法中使用它!

相关方法:

  • String getServletName():获取Servlet在web.xml文件中的配置名称,即指定的名称;
  • ServletContext getServletContext():用来获取ServletContext Application域对象
  • ServletContext在服务器启动时创建,服务器关闭时销毁;
  • 获取方式:1. ServletConfig 获取 ; 2. GenericServlet类中有getServletContext();可直接调用;
  • String getInitParameter(String name):用来获取在web.xml中配置的初始化参数,通过参数名来获取参数值;
  • Enumeration getInitParameterNames():用来获取在web.xml中配置的所有初始化参数名称;

servlet 四大域

Application 域 全局域,整个web项目有用;

session 域 会话域

request 域 请求域

page 域 页面域

四大域对象:

  • ServletContext;
  • HttpSession;
  • ServletRequest;
  • PageContext;

域对象的一些方法

  • getAttribute(String name) 获取对应的数据
  • getAttributeNames()获取所有的key
  • removeAttribute(String name) 移除对应的数据
  • SetAttribute(String name, Object object) 设置数据

IDEA与tomcat相关配置

IDEA会为每一个tomcat部署的项目单独创建一份配置文件,配置文件在哪里呢?我们启动tomcat的时候,在控制台可以看到相应信息;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RBcI9Dip-1667116846706)(C:\Users\22496\Desktop\images\idea 与 tomcat 部署.png)]

项目文件存放位置;

工作空间项目和tomcat部署的web项目

  • tomcat真正访问的是“tomcat部署的web项目” 即 IDEA下的out 目录中的内容 ,“tomcat部署的web项目"对应着"工作空间项目” 的web目录下的所有资源
  • WEB-INF目录下的资源不能被浏览器直接访问。

request

在客户端发出每个请求时,服务器都会创建一个request对象,并把请求数据封装到request中,然后在调用Servlet.service()方法时传递给service()方法,这说明在service()方法中可以通过request对象来获取请求数据。

  • 请求头

  • String getHeader(String name):获取指定名称的请求头;

  • Enumeration getHeaderNames():获取所有请求头名称;

  • int getIntHeader(String name):获取值为int类型的请求头。

  • 请求参数

  • String getParameter(String name):通过指定名称获取参数值;

  • 前端传递请求参数名,没有传递值 username=&email=111,获取到"";

  • 前端没有传递请求参数名,结果为null

  • String[] getParameterValues(String name):当多个参数名称相同时,可以使用方法来获取;例如多选框

  • Map getParameterMap():获取所有参数封装到Map中,其中key为参数名,value为参数值,因为一个参数名称可能有多个值,所以参数值是String[],而不是String。

  • Enumeration getParameterNames():获取所有参数的名字;

  • 域对象功能

  • 请求转发和包含

//获取转发器
RequestDispatcher rd = request.getRequestDispatcher(“/BServlet”);
//转发
rd.forward(request, response);




```java

+ 其他方法

- int getContentLength():获取请求体的字节数,GET请求没有请求体,没有请求体返回-1;
- String getContentType():获取请求类型,如果请求是GET,那么这个方法返回null;如果是POST请求,那么默认为application/x-www-form-urlencoded,表示请求体内容使用了URL编码;
- String getMethod():返回请求方法,例如:GET
- Locale getLocale():返回当前客户端浏览器的Locale。java.util.Locale表示国家和言语,这个东西在国际化中很有用;
- String getCharacterEncoding():获取请求编码,如果没有setCharacterEncoding(),那么返回null,表示使用ISO-8859-1编码;
- void setCharacterEncoding(String code):设置请求编码,只对请求体有效!注意,对于GET而言,没有请求体!!!所以此方法只能对POST请求中的参数有效!
- String getContextPath():返回上下文路径,例如:/hello
- String getQueryString():返回请求URL中的参数,例如:name=zhangSan
- String getRequestURI():返回请求URI路径,例如:/hello/oneServlet
- StringBuffer getRequestURL():返回请求URL路径,例如:http://localhost/hello/oneServlet,即返回除了参数以外的路径信息;
- String getServletPath():返回Servlet路径,例如:/oneServlet
- String getRemoteAddr():返回当前客户端的IP地址;
- String getRemoteHost():返回当前客户端的主机名,但这个方法的实现还是获取IP地址;
- String getScheme():返回请求协议,例如:http;
- String getServerName():返回主机名,例如:localhost
- int getServerPort():返回服务器端口号,例如:8080




response

在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。

  • 设置响应头信息;

  • response.setHeader(“content-type”, “text/html;charset=utf-8”):设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);

  • response.setHeader(“Refresh”,“5; URL=http://www.baidu.com”):5秒后自动跳转到百度主页。

  • 发送状态码;

  • response.setContentType(“text/html;charset=utf-8”):等同与调用response.setHeader(“content-type”, “text/html;charset=utf-8”);

  • response.setCharacterEncoding(“utf-8”):设置字符响应流的字符编码为utf-8;

  • response.setStatus(200):设置状态码;

  • response.sendError(404, “您要查找的资源不存在”):当发送错误状态码时,Tomcat会跳转到固定的错误页面去,但可以显示错误信息。

  • 设置响应正文;

  • 通过获取字符流 或者 字节流 输出响应内容;

  • PrintWriter out = response.getWriter():获取字符流;

  • response.getWriter()是PrintWriter类型,所以它有缓冲区,缓冲区的默认大小为8KB。

  • 调用response.flushBuffer()方法来手动刷新缓冲区;

  • ServletOutputStream out = response.getOutputStream():获取字节流;

  • 当我们响应数据之前,需要设置文本类型及编码;setContentType();

  • 注意!!! 在一个请求中,不能同时使用这两个流!不然会抛出IllegalStateException异常。

  • 重定向;

//重定向
response.sendRedirect(“http://www.baidu.cn”);




  • 重定向是两次请求;

  • 重定向的URL可以是其他应用,不局限于当前应用;

  • 重定向的响应头为302,并且必须要有Location响应头;

  • 重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;




转发与重定向的区别:

  • 请求转发是一个请求,而重定向是两个请求;
  • 请求转发后浏览器地址栏不会有变化,而重定向会有变化,因为重定向是两个请求;
  • 请求转发的目标只能是本应用中的资源,重定向的目标可以是其他应用;
  • 请求转发对AServlet和BServlet的请求方法是相同的,即要么都是GET,要么都是POST,因为请求转发是一个请求;
  • 重定向的第二个请求一定是GET;
  • 请求转发是在服务端内部执行的,而重定向是在客户端执行的.

Servlet 编码问题

我们常说的文本都存在编码问题;在计算机底层以及io传输的过程中,都是以字节的形式存在的;在获取字节流后,利用相应的编码表转成相应的字符;常见的编码有 Ascall 码,utf-8,GBK,ISO-8859-1 (西欧编码)等

ascall 码表里包含了所有的英文字母,而其他所有的编码都是在ascall 码的基础上扩展的,所以英文在任何编码里都不会乱码;而像其他语言就会因为编码的问题而乱码; 例如 同样的一个中文字,它在a编码里对应1120;而在b编码表里对应1563;那么当它在a编码环境中会显示正确,而在b编码环境中就会显示异常;

所以解决乱码问题就是统一编码规则即可;

在web 项目中

  • html页面一般是UTF-8编码,
  • 浏览器(chrom)的默认编码是UTF-8;
  • tomcat服务器处理请求的默认编码是ISO-8859-1 ;
  • IDEA 编辑器的编码全都设置为UTF-8;
  • get请求没有请求体,不能直接通过请求对象设置编码;

  • 在tomcat 7 以及以前的版本,它没有默认处理get 请求的编码;在8版本及以后的版本,tomcat默认处理get请求的编码,将其指定为utf-8,此时我们拿到的就是正确的没有乱码的结果;

  • tomcat 7之前既然没有默认指定get编码,那么怎么手动改编码呢?

//通过代码改编码
String name = request.getParameter(“name”);
//先获得字节数组通过 服务器编码 ;在利用utf-8 编码装换成我们需要的字符;
name = new String(name.getBytes(“iso-8859-1”), “utf-8”);



```xml

+ ```xml
 <!--tomcat 改配置文件加 URIEncoding= "UTF-8" --> 
 <Connector URIEncoding= "UTF-8"  connectionTimeout= "20000"  port= "8888"  protocol= "HTTP/1.1"  redirectPort= "8443" />


+ post
+ 两种方式
+ 设置请求编码 :request.setCharacterEncoding(“utf-8”);
+ 设置响应编码:response.setContentType("text/html; charset=utf-8 ");
+ 响应编码 只设置 setCharacterEncoding(“utf-8”); 只设置了响应流的编码,没有指定浏览器编码;
+ 当我们使用setContentType("text/html; charset=utf-8 "); 时,它的响应流编码默认跟浏览器编码一致,所以只设置响应浏览器编码即可;

解决编码问题的相关代码 要写在操作数据之前的;即先编码,后使用;

jsp

jsp概述

jsp 既可以写html ,又可以写java代码;

<% %> java代码入口,相当于main函数; 多个<% %>可以通用

<%= %> 表达式的值输出到页面

<%! %> 定义属性和方法,相当于java类



  <%
     int a = 10;
     if(a==10){
       out.print("<p>"+a+"</p>");
     }
  %>

<%--  内容输出到页面,相当于out.print--%>
  <%= a %>
<%--  定义属性和方法,相当于类--%>
  <%!

    private String str;
    private void fun(){
      System.out.println(str);
    }
  %>

  <%
    this.str="123";
    fun();
  %>

jsp九大内置对象

  • pageContext page域对象
  • request 请求对象(请求域)
  • session session域对象
  • application 全局域对象
  • response 响应对象
  • out 输出流对象
  • config 配置
  • page 相当于this
  • exception 异常

html转jsp

  • 创建与html同名jsp文件,

  • 把html页面的所有内容拷贝到jsp, 从<%@ page%> 之后

  • 把相对路径转换为绝对路径, 项目设置发布项目名: / 绝对路径: 全部以 /开头

如果设置发布项目名: /xx 绝对路径: /xx开头, /xx动态获取: <%=request.getContextPath()%>

EL表达式

<%= %> 往页面输出内容: 如果内容为null(空对象), 也会在页面显示

EL 表达式 ${域中的属性名(k值)} ${对象.属性名..}获取对象属性

  • 查找所有的域
  • 从小范围的域–》大范围的域,即page域(若没找到)到application域
  • 若所有的域都没找到,返回null值,在页面不显示

JSTL标签

  • 作用: 替换java脚本, 配合EL标签式,

  • 执行在服务器端执行, 把jstl执行之后的结果响应给客户端浏览器,

  • JSTL标签在Html标签之前执行

  • 使用步骤

  • 导入jstl依赖:

  • 在使用jstl标签的jsp页面, 使用 taglib指令,导入标签库

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


prefix: 前缀, 任意取名, 规范名: core标签库:  c    比如:  `<c:div>`  使用前缀区分html标签

core所有的标签名:  `<c:标签名>`

uri: 对应jstl标签的url, 固定写法,  导入jstl标签库, 选择的是  jsp/jstl的标签库


使用:

<!-- if(){} -->
<c: if test="${a==null}">
	<h1>
        a是null
    </h1>
</c:>

<!-- if else if else -->
<!-- choose标签里不能加注释-->
<c:choose>
	<c:when test="">
    	
    </c:when>
    <c:when test="">
    	
    </c:when>
    <c:otherwise test="">
    	
    </c:otherwise>
</c:choose>

<!-- 循环 -->
<!-- 普通循环-->
<c:forEach var="i" begin="0" end="4" step="1">
	
</c:forEach>
<!--增强for-->
<c:forEach var = "admin" items ="${adminList}">
	
</c:forEach>

for循环: 有一个varStatus=“变量” , 得到for循环的循环状态对象,该对象有以下属性:

  • count:int类型,当前以遍历元素的个数; 第几次循环,从1开始
  • index:int类型,当前元素的下标; 从0开始
  • first:boolean类型,是否为第一个元素;
  • last:boolean类型,是否为最后一个元素;

Cookie

Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。相当于一个身份的标识;

Cookie由服务器创建,在第一次请求的时候,响应(发)给客户端;在以后的每次客户端发请求时,都会带上Cookie,服务器也会返回Cookie;用于身份识别;

Cookie在不同的浏览器之间是不共享的;

Cookie k-v键值对 ,相同的k可以覆盖原有的值;

tomcat 7 及之前,Cookie不支持中文;解决:URL编码;

String str ="中国";  
//URL编码
String str1 = URLEncoder.encode(str, "UTF-8");
System.out.println(str1);  //%E4%B8%AD%E5%9B%BD

//URL解码
String str2 = URLDecoder.decode(str1, "UTF-8");
System.out.println(str2);  //中国

tomcat 8以及以后,Cookie支持中文;

Cookie操作

//服务器创建Cookie
Cookie cook1 = new Cookie("name","张三");
Cookie cook2 = new Cookie("age","28");

//传Cookie,响应返回Cookie 
response.addCookie(cookie1);
response.addCookie(cookie2);

//拿Cookie
Cookie[] cs = request.getCookies();//获取请求中的Cookie


//Cookie 类的相关方法
cook.getName();
cook.getValue();
//设置Cookie存活时间
//参数单位为秒;
//默认值 -1, 是会话级别存活,即浏览器关闭窗口;
// 参数 0 为立即删除
cook.setMaxAge(int count);

//设置Cookie 访问路径
//如果servlet 请求路径包含Cookie路径,会在请求中带上这些Cookie;
//这里的包含是指 
// 例如 访问路径为 localhost:8080/a/b/c ; 它包含的路径有:/a; /a/b; /a/b/c;  
cook.setPath();

//修改value值
cook.setValue();

//若path不同,即使key相同,也是不同的Cookie

Session

javax.servlet.http.HttpSession接口表示一个会话,我们可以把一个会话内需要共享的数据保存到HttSession对象中!

获取Session :

  • HttpSession request.getSesssion():如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回;
  • HttpSession request.getSession(boolean):当参数为true时,与requeset.getSession()相同。如果参数为false,那么如果当前会话中存在session则返回,不存在返回null;
//设置session失效;一般作退出使用
void invalidate();

//设置最大存活时间
void setMaxInactiveInterval(int interval);

//获取sessionid
String getId();

//域对象的相关方法;get,set,remove;

session原理:

  • 服务器在创建session时,会给每一个客户端生成一个sessionid用来做身份识别;这个sessionid被放在Cookie中(也就是一个k-v键值对),随着服务器的响应,客户端接收Cookie,得到sessionid;在下一次请求中,通过sessionid,去服务器对应的session块中交换数据;
  • 在服务器中,tomcat维护了一个session池,里面存放了各个客户端的seeion,它们会通过sessionid来区分;每一个session的默认存活时间为30分钟,即离上一次访问session的时长;
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cmijyoD4-1667116846709)(C:\Users\22496\Desktop\实训三\javaweb\javaWeb新版\文档\assets\wps8-1665588799705.jpg)]

当浏览器关闭,Cookie(客户端)销毁,session(服务器)就不会被访问,经过设定的存活时间,就会被服务器清理;

Filter

拦截请求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DCzcEfHY-1667116846710)(C:\Users\22496\Desktop\images\Filter.png)]

实现:

  1. 编写一个类实现javax.servlet.Filter接口
  2. 在web.xml文件或者使用注解, 对过滤器进行配置, 配置过滤器拦截那些请求的url

拦截后放行:

filterChain.doFilter(servletRequest,servletResponse);

过滤器的执行顺序:

web.xml配置文件: 过滤器的配置文件决定过滤器执行顺序

​ 由过滤器的<filter-mapper>顺序决定的, 谁的<filter-mapper>在前,谁先执行

<filter>
    <filter-name>AFilter</filter-name>
    <filter-class>Filter.CheckLoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AFilter</filter-name>
    <url-pattern>/AFilter</url-pattern>
</filter-mapping>

在web3.0提供注解@WebFilter的配置方式:

使用注解的方式, 过滤器执行的顺序, 由过滤器名字决定, 多个过滤器, 推荐使用web.xml配置

@WebFilter(filterName = "CheckLoginFilter",value = "/user/*")

文件上传

文件上传时

对于小文件,我们一般将它存在服务器上;

前端:

  • 使用表单元素: <input type="file"/>
  • 提交方式: POST,请求体上传;
  • from 表单的 enctype 的值"multipart/form-data"

后端:

  • 当from表单的 enctype 的值"multipart/form-data",request.getParamter()这个方法失效
  • 通过请求对象的ServletInputStream得到数据, 借助第三方的jar, apache提供的 commons-fileupload.jar,commons-io.jar ;

使用Commons-fileupload步骤

  1. 导入依赖
  2. 创建DiskFileItemFactory, 工厂类, FileItem: 对应表单的表单项(input,select,teaxarea)
  3. 创建一个解析Request对象解析器 ServletFileUpload
  4. 解析Request对象 ServletFileUpload的 List<FileItem> parseRequest(request)
  5. 遍历第4步的 得到List<FileItem> 得到一个一个FileItem,根据FileItem类型(普通表单项,非普通表单项(文件表单))

@WebServlet( "/uploadServlet")
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求参数
        //String username = request.getParameter("username"); //失效
        //System.out.println(username); //null
        //ServletInputStream inputStream = request.getInputStream();

        //借助于 commons-fileupload
        //1.创建DiskFileItemFactory对象
        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();

        //2.创建一个解析Request对象解析器 ServletFileUpload
        ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);

        try {
            //3.解析Request对象
            List<FileItem> fileItems = servletFileUpload.parseRequest(request);

            //4.遍历fileItems
            for (FileItem fileItem : fileItems) {
                //5.判断fileItem是否是一个普通表单项
                // true 普通表单项  false: 非普通表单项  文件表单项
                if(fileItem.isFormField()){ //true  普通表单项
                   //表单项的name getFieldName() // getName() 上传的文件名
                    String fieldName = fileItem.getFieldName();
                    //表单项的value  getString(String charset)
                    String value = fileItem.getString("UTF-8");
                    System.out.println(fieldName+":"+value);

                }else{ //非普通表单项  文件表单项
                    //上传的文件保存到服务器的硬盘上
                    String savePath = "D:/upload/";
                    //得到上传的文件名 getName()
                    String uploadFilename = fileItem.getName();
                    //注意问题: 服务器保存的文件名不能直接使用用户上传的文件名
                    //保证每一个文件名唯一的  时间戳(毫秒)+用户名+...
                    //                    UUID(随机生成32位16进账字符串)
                    //保存 FileItem的write(File file)
                    //使用UUID
                    // 创建一个文件名  文件名称 + 后缀名(上传文件的后缀名)
                   String saveFile =  FileUploadUtil.randomFilename()+FileUploadUtil.getFileSuffix(uploadFilename);
                   fileItem.write(new File(savePath,saveFile));

                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

Ajax

什么是Ajax

​ AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。目前流行json数据;

​ AJAX还有一个最大的特点就是,当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新。这一特点给用户的感受是在不知不觉中完成请求和响应过程。

同步交互和异步交互的区别:

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

Ajax核心对象

其实AJAX就是在Javascript中多添加了一个对象:XMLHttpRequest对象。通过这个对象完成异步交互;

多个异步请求并不是同时被服务器处理,而是在XMLHttpRequest 对象的作用下,组成了一个阻塞队列,服务器依次处理这些请求,这里有一个排队的机制在里面;

jQuery 中的Ajax

$.ajax()可以通过发送HTTP请求加载远程数据,是jQuery最底层的AJAX的实现,具有较高灵活性:

$.ajax({
                   //请求路径
                   url:getPath()+"/AServlet",
   				//请求方法
                   type:"GET",
   				// 请求参数
                   data:"name=张三",
   				// 返回数据类型
                   dataType:"text",
   				// 请求成功的回调函数
                   // 参数date 为 返回参数;
                   success:function(data){
                       alert(data);
                   }
				});

JQuery封装的发送HTTP GET请求从服务器加载数据的AJAX方法:

// get 
$.get(url,data,success(resp,status,xhr),dataType)

// post
$.post(url,data,success(resp,status,xhr),dataType);

Json

什么是json

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式 (字符串类型)。

JSON是用字符串来表示Javascript对象,例如可以在Servlet中发送一个JSON格式的字符串给客户端Javascript,Javascript可以执行这个字符串,得到一个Javascript对象。

json 语法:

  • 花括号保存对象
  • 方括号保存数组
  • k-v结构
  • key要在双引号中,不能使用单引号
  • 字符串必须使用双引号表示,不能使用单引号
  • value值可以为null
var person = ' {"name":"zhangSan",
              "age":"18", 
              "sex":"male"} ';

{
  "employees": [
        { "firstName":"Bill" , "lastName":"Gates" },
        { "firstName":"George" , "lastName":"Bush" },
        { "firstName":"Thomas" , "lastName":"Carter" }
	]
}

json 序列化

javascript:

//json -> javascript
JSON.parse(text[, reviver])

//javascript --> json
JSON.stringify(value[, replacer [, space]])

java:

​ 采用第三方 jar包 fastjson.jar

​ fastjson优点:速度快、使用广泛、使用简单、功能完备、测试完备(之前爆了很多漏洞),现在使用fastjson至少升级到1.2.60版本

fastjson 三大对象

  • JSON
  • 主要用于转换json;
  • JSONObject
  • JSONArray

如果想得到指定格式的日期字符串,我们可以使用@JSONField(format = "yyyy-MM-dd")注解进行日期格式化

//日期格式化
@JSONField(format = "yyyy-MM-dd")
//不可序列化,即json中会隐去该字段
@JSONField(serialize=true)
private Date birthday;

T parseObject(String text, Class<T> clazz)  //把json转换为一个java对象
JSONObject parseObject(String text)    // 把json转换为一个JSONObject对象
List<T> parseArray(String text, Class<T> clazz)  //把json转换为一个List集合
JSONArray parseArray(String text)     //把json转换为一个JSONArray对象
String toJSONString(Object object) //把一个java对象转换为json格式的字符串 
    
    
Person person = new Person("liSi", 18, "female");
//把java对象转换为json字符串
String json = JSON.toJSONString(person);
System.out.println(json);
    

(text[, reviver])

//javascript --> json
JSON.stringify(value[, replacer [, space]])


java:

​     采用第三方 jar包 fastjson.jar

​	fastjson优点:**速度快、使用广泛、使用简单、功能完备**、测试完备(之前爆了很多漏洞),现在使用`fastjson`至少升级到`1.2.60`版本

>fastjson   三大对象
>
>+ JSON
>  + 主要用于转换json;
>+ JSONObject
>+ JSONArray
>
>
>
>如果想得到指定格式的日期字符串,我们可以使用`@JSONField(format = "yyyy-MM-dd")`注解进行日期格式化
>
>```java
>//日期格式化
>@JSONField(format = "yyyy-MM-dd")
>//不可序列化,即json中会隐去该字段
>@JSONField(serialize=true)
>private Date birthday;
>
>```
>
>

```java
T parseObject(String text, Class<T> clazz)  //把json转换为一个java对象
JSONObject parseObject(String text)    // 把json转换为一个JSONObject对象
List<T> parseArray(String text, Class<T> clazz)  //把json转换为一个List集合
JSONArray parseArray(String text)     //把json转换为一个JSONArray对象
String toJSONString(Object object) //把一个java对象转换为json格式的字符串 
    
    
Person person = new Person("liSi", 18, "female");
//把java对象转换为json字符串
String json = JSON.toJSONString(person);
System.out.println(json);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值