servlet2

声明:该博客为学习b站某servlet教学视频的笔记,仅供以后复习之用

HTTP协议

HTTP

超文本传输协议,基于请求与响应模式、无状态的、应用层的协议,运行于TCP协议基础上

HTTP协议特点

  1. 支持B/S模式

  2. 请求的方法常用有:GET、POST等,客户端发送请求方法和路径,服务器即可响应数据,因而通信速度快

  3. 灵活:HTTP允许传输任意类型数据,传输的数据由Content-Type标识

  4. 无连接:每次TCP连接只处理一个或多个请求,服务器处理完客户请求后,即断开连接

    分为短连接(HTTP1.0)和长连接(HTTP1.1)

  5. 无状态:指协议对于事务处理没有记忆能力

HTTP协议通信流程

  1. 客户端与服务器建立连接(三次握手)
  2. 客户向服务器发送请求
  3. 服务器接收请求,并根据请求返回相应的文件作为应答
  4. 客户与服务器关闭连接(四次挥手)

HTTP1.1多个请求和响应过程可以重叠进行,增加了请求头和响应头

状态码

状态代码状态描述说明
200OK客户端请求成功
302Found临时重定向
403Forbidden服务器收到请求,但是拒绝提供服务,服务器通常会在响应正文中给出不提供服务的原因
404Not Found请求的资源不存在,比如输入了错误的URL
500internet Server Error服务器发生不可预期的错误,导致无法完成客户端的请求

Servlet详解

Servlet核心接口和类

Servlet体系中除了实现接口,还可以通过genericServlet或HttpServlet类,来完成编写

Servlet API

public class MyServlet 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("My First Web Servlet");
        System.out.println(new Date());
    }

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

    @Override
    public void destroy() {

    }
}

GenericServlet抽象类

提供了生命周期init和destroy的简单实现,只需要重写抽象方法service()

public class GenServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("123454321");
    }
}

HttpServlet类

HttpServlet是继承GenericServlet的基础上进一步的扩展

HttpServlet的子类至少必须重写一个方法,通常为:

doGet			如果servlet支持HTTP  GET请求
doPost			用于HTTP  POST请求
doPut			用于HTTP	Put请求
doDelete		用于HTTP	Delete请求

常见错误

HTTP404错误 资源找不到

  1. 地址栏书写错误
  2. 地址栏没有问题,把IDEA中out目录删除,然后重新运行

Servlet地址配置重复(运行Tomcat时就会报错 web.xml出现重复)

Servlet地址出现错误,比如说没有加"/"

Servlet的两种配置方式

  1. 使用web.xml(servlet2.5之前使用) 通用型

    url-pattern定义匹配规则
    精准匹配				/具体名称				只有url路径是具体名称才会触发servlet
    后缀匹配				*.xxx					只要是以xxx结尾的就会触发servlet
    通配匹配				/*					   匹配所有的请求,包含服务器所有资源
    通配符匹配				/					  匹配所有请求,包含服务器所有资源,不包括.jsp
    -------------------------------------------------------------------------------------------
    load-on-startup
    1.元素标记容器在web应用程序启动的时候就加载这个servlet
    2.它的值必须是一个正整数或0,标识servlet被加载的顺序,标识容器在应用启动时就加载该servlet,值越小优先级越高
    3.当值为负数或者没有设置时,表示当访问该servlet时才被加载
    
    <servlet>
            <servlet-name>my</servlet-name>
            <servlet-class>com.MyServlet</servlet-class>
            <load-on-startup>0</load-on-startup>
    </servlet>
    
  2. 使用注解(servlet3.0后支持)

@WebServlet(value = {"/gs","/gss"},loadOnStartup = 1)
public class GenServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("123454321");
    }
}

常用属性
value		配置url路径,可以配置多个
urlPatterns	 配置url路径,和value作用一样,不能同时使用
loadOnStartup 配置servlet的创建时机,如果时0或者整数,启动程序时创建,如果是负数,则访问时创建

注解和web.xml可以同时生效

Servlet应用(重点)

request对象

在servlet中用来处理客户端请求需要用doGet或者doPost方法的request对象

get和post的区别

get请求
	1.get提交的数据放在url之后,以?分割URL和传输数据,参数之间使用&相连
	2.get方式明文传递,数据量小,不安全
	3.效率高,浏览器默认请求方式为GET请求
	4.对应的servlet的方法是doPost
post请求
	1.post方法是把提交的数据放在HTTP包的body中
	2.密文传递数据,数据量大,安全
	3.效率相对没有GET高
	4.对应的servlet方法是doPost

request主要方法

方法名说明
String getParameter(String name)根据表单组件名称获取提交的数据
void setCharacterEncoding(String charset)指定每个请求的编码

response主要方法

response负责响应的主要内容

主要方法

方法名称作用
setHeader(name,value)设置响应信息头
setContenttype(String)设置响应文件类型,响应式的编码格式
setCharacterEncoding(String)设置服务端响应内容编码格式
getWriter()获取字符输出流
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //对request请求对象设置为统一的编码
        req.setCharacterEncoding("UTF-8");
        //1.获取用户请求发送的数据
        String username = req.getParameter("username");
        String password = req.getParameter("pwd");
        System.out.println("提交的数据:"+username+"\t"+password);

        //2.响应数据给客户端
       // resp.setCharacterEncoding("UTF-8");//设置响应格式为UTF8
	  // resp.setHeader("Content-Type","text/html;charset=UTF8");
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter printWriter = resp.getWriter();
        printWriter.println("register success!注册成功!");
    }
 ---------------------------------------------------------------------------------------------   
 <body>
    <form action="/WebProject_war_exploded/rs" method="post">
        用户名:<input type="text" name="username" /><br>
        密码:<input type="password" name="pwd" /><br>
        <input type="submit" value="注册">
    </form>
</body>

Servlet实现转发跳转

现有问题

调用业务逻辑和显示结果页面都在同一个servlet中,就会产生设计问题
	1.不符合单一职能原则,各司其职思想
	2.不利于后续维护
因此应该将业务逻辑与显示结果分离开来


xxxxServlet extends HttpServlet{
	//调用业务逻辑
	//显示结果页面
}

将业务逻辑与显示结果分离
xxxController extends HttpServlet{
	//调用业务逻辑
}
xxxJsp extends HttpServlet{
	//显示页面结果
} 

存在两个问题:
	1.业务逻辑与显示结果分离后,如何跳转到显示结果的servlet
	2.业务逻辑得到的数据结果如何传递给显示结果的servlet

转发

转发的作用在服务器端,将请求发送给服务器其他资源,来共同完成一次请求的处理

页面跳转
在调用业务逻辑的servlet中编写:
request.getRequestDispatcher("/目标URL-pattern").forward(request,response);

使用forward跳转时,是在服务器内部跳转,地址栏不发生改变,属于同一次请求

数据传递
forward表示一次请求,是在服务器内部跳转,可以共享同一次request作用域中的数据
request作用域:拥有存储数据的空间,作用范围是一次请求有效(一次请求可以经过多次转发)
	1.可以将数据存入request后,在一次请求过程中的任何位置进行获取
	2.可传递任何类型数据(基本类型数据、对象数组、集合等)
存数据:request.setAttribute(key,value);
	以键值对形式存储在request作用域中,key为类型,value为Object类型
取数据:request.getAttribute(key);
	通过String类型的key访问Object类型的value
----------------------------------------------------------------------------------------------------
 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        AdminService adminService = new AdminServiceImpl();

        List<Admin> adminLists = adminService.showAllAdmin();
        req.setAttribute("admin",adminLists);
        req.getRequestDispatcher("/showAlljsp").forward(req,resp);
    }
    

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter printWriter = resp.getWriter();
        List<Admin> adminLists = (List<Admin>)req.getAttribute("admin");
        if(adminLists != null){
            //打印数据在页面中
            printWriter.println("<html>");
            printWriter.println("<head>");
            printWriter.println("<meta charset='UTF-8'>");
            printWriter.println("<title>显示所有</title>");
转发特点
1.转发是服务器行为
2.转发是浏览器只做了一次访问请求
3.转发浏览器地址栏不变
4.转发两次跳转之间传输的信息不会丢失,所以可以通过request进行数据的传递
5.转发只能将请求转发给同一个web应用中的组件(同一个web项目中进行转发)

重定向

重定向作用在客户端,客户端将请求发送给服务器后,服务器响应给客户端一个新的请求地址,客户端重新发送新请求

页面跳转
在调用业务逻辑的servlet中,编写以下代码:
	response.sendRedirect("目标URI");
URI:统一资源标识符,用来表示服务器中定为一个资源,资源在web项目中的路径(/project/source)
路径要给全,指定哪一个项目下的哪一个资源
数据传递
sendRedirect跳转时,地址栏发生改变,代表客户端重新发送的请求,属于两次请求
	response没有作用域,两次request请求中的作用域无法共享
	传递数据:通过URI的拼接进行数据传递{"/WebProject/b?username=ton"}
	获取数据:request.getParameter("username");
注:只能传递string类型数据
重定向特点
1.重定向是客户端行为
2.重定向是浏览器至少做了两次访问请求
3.重定向浏览器地址改变
4.重定向两次跳转之间传输的信息会丢失(request范围)
5.重定向可以指向任何资源,包括当前应用程序的其他资源,同一个站点上的其他应用程序中的资源,其他站点的资源	

转发重定向总结

当两个或多个servlet需要传递数据时,选择forward转发,不建议使用sendRedirect进行传递

Servlet生命周期

实例化

当用户第一次访问servlet时,由容器调用servlet构造器创建具体的servlet对象,也可以在容器启动后立刻创建实例,使用如下代码可以设置servlet是否在服务器启动时创建

1

注意:只执行一次

初始化

在初始化阶段,init()方法会被调用

注意:init只执行一次

服务

当客户端有一个请求时,容器就会将请求ServletRequest与响应ServletResponse对象转给servlet,以参数的形式传给service方法

此方法会执行多次

销毁

当servlet容器停止或者重新启动都会引起销毁servlet对象并调用destroy()方法

destroy()方法执行一次

servlet特性

servlet安全问题
servlet访问后,会执行实例化操作,创建一个servlet对象,而Tomcat容器可以同时多个线程并发访问同一个servlet,如果在方法中对成员变量做修改操作,就会有线程安全问题
如何保证servlet安全
1.synchronized:将存在线程安全问题的代码放到同步代码块中
2.实现SingleThreadModel接口
	servlet实现SingleThreadModel接口后,每个线程都会创建servlet实例,每个客户端请求就不存在资源共享问题,但是servlet响应客户端效率太低,所以已经被淘汰
3.尽可能地使用局部变量
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页