Servlet (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的时候,在控制台可以看到相应信息;

请添加图片描述

项目文件存放位置;

工作空间项目和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):通过指定名称获取参数值;

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

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

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

  • 域对象功能

  • 请求转发和包含

  •   	//获取转发器	
    	RequestDispatcher rd = request.getRequestDispatcher("/BServlet");
        //转发
        rd.forward(request, response);	
    
  • 其他方法

  • 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);
    
  • <!--tomcat 改配置文件加 URIEncoding= "UTF-8" --> 
    <Connector URIEncoding= "UTF-8"  connectionTimeout= "20000"  port= "8888"  protocol= "HTTP/1.1"  redirectPort= "8443" />
    
  • post

  • 两种方式

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

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

  • 两种方式

  • request.setCharacterEncoding(“utf-8”);

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值