jsp总结


正在总结中,错误地方请指教改正!

MVC设计模式

MVC是Model-View-Controller的首字母缩写,是(模型-试图-控制器),它是一种框架,并不是23种设计模式之一。


  • model:是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性
  • view:负责展示数据到界面并与用户交互。
  • controller:是指控制器,接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据

  • mvc它强制性地使应用程序的输入、处理和输出分开,使程序分为三个核心的部件,这么做的最大目的是解耦,在mvc没出来之前所有的代码都写在jsp界面,也就是(all in one)这样虽然开发相对简单、快速,但是代码之间存在强耦合,这种开发适合早期为了让程序早日上线,但效率并不是太高,很显然这些不是我们希望看到的,我们想看到的是(弱耦合,高内聚),mvc分层能够很好的解决这一问题。

mvc实现了程序流程控制、页面展示、业务逻辑的分离

include指令和jsp:include动作

相同点:
  • 都是把文件导入到当前页面
  • 都可以减少代码复用,避免代码的重复书写,使代码结构清晰,容易维护
  • 导入位置都是include或jsp:include代码书写位置

不同点:
  • jsp:include基本语法为:

  • include指令基本语法为:
    <%@include file="url"%>

  • jsp:include包含文件类型可以是静态的也可以是动态的,include指令只能包含静态文件

  • jsp:include是在页面访问时被导入的,include是在jsp引擎编译成servlet时导入的。

  • jsp:include动作包含的文件和主页面是两个相对独立的文件,被编译成两个servlet文件,include会把被包含的文件的主页面编译为一个servlet文件,因为jsp:include需要每次访问时加载,所以效率上相对慢一点

  • 静态文件就是网站所使用到的所有提前写好的css、js、第三方的前端模块、图片文件、都叫做静态文件资源

  • 动态文件就是针对Mosaic系统指一段在www客户端执行的程序,并且用来产生显示给用户的信息。动态文件的执行可能会导致客户端执行一系列动作从而影响最终结果的产生。例如存取其他文件,产生新的HTML,获得客户端的位置信息。也可能会产生一个完整的X接口。动态文件可以是超文本标记语言(HTML)文档。可使WEB客户端能够自动感知移动计算情景的变化。


转发与重定向

重定向:

是指当浏览器请求一个URL时,服务器返回一个重定向指令,告诉浏览器地址已经变了,麻烦使用新的URL再重新发送新请求。


转发:

用于将请求转发给一个HTML文件,JSP文件,或者是一个程序段。这里的转发是指:之前的request不变,而继续由转发后的文件或程序处理。


重定向:两次请求,状态码302 301,地址栏URL会发生变化。
转发:一次请求 状态码200,地址栏URL不会发生变化。
1.请求转发和重定向都可以实现访问一个资源时转向当前应用资源
2.请求转发是一次请求一次响应,而重定向为两次请求两次响应
3.一般情况下应该使用请求转发,减少浏览器对服务器的访问,减轻服务器压力
4.如果需要改变浏览器的地址栏,或更改浏览器的刷新按钮的功能时需要使用重定向

可以看这个代码获取的信息能够在数据库中查到就重定向到success.jsp界面,如果失败就转发到login.jsp界面。


可以看到登录成功的操作,有两次请求,重定向获取url,然后转发。第一次状态码是302,第二次是200。


登录失败直接转发到login.jsp界面,状态码是200,一次请求。

我们可以发先重定向需要的时间是转发耗费时间的,我把登录失败转发换成重定向比较发现也是这样的,毕竟重定向需要两次请求服务器。


Servlet的生命周期


  • servlet生命周期有三个阶段:初始化(包括装载和初始化)、运行、消亡。

  • 初始化阶段:初始化阶段分为装载和初始化两个子阶段。

    • 装载就是由Servlet容器装载一个Servlet类,把它装载到java内存中,Servlet容器可创建一个Servlet对象并与web.xml中的配置(也可以采用注解的方式@WebServlet)得路径对应起来;
    • 初始化阶段是调用init()方法,在整个Servlet生命周期中init()方法只被调用一次。
  • 运行阶段:在这个阶段中会实际响应客户端的请求,当有请求时Servlet会创建HttpServletRequest和HttpServletResponse对象,然后调用service(HttpServletRequest request,HttpServletResponse response)方法,service()方法通过调用request对象获得请求对象的信息并加以处理,再由response对象对客户端做出响应。

  • 消亡阶段:当Servlet应用被终止后,Servlet容器会调用destroy()方法对Servlet对象进行销毁,在消亡过程中,Servlet容器将释放被它占用的资源,例如关闭流,关闭数据库连接等。同样在整个Servlet生命周期中destroy()方法只调用一次。


Servlet得生命周期

运行阶段如果重写了service方法doGet和doPost方法将不会调用,直接由service来管理转向方法


使用xml配置servlet


        loginServlet
        com.hjk.servlet.LoginServlet
    
    
        loginServlet
        /login
    

文件上传与下载

学习文件上传与下载,首先要了解I/O流。
I/O流就是输入/输出流,包括字节流,字符流,缓冲流,随机流,数组流,数据流,对象流等。
我们只需要了解字节流(按字节读取),字符流(按字符读取)。

了解完I/O流就可以学习文件上传与下载了
文件上传:就是文件数据上传到java程序。

  • 文件上传需要使用form表单进行提交数据,并且form表单的enctype属性必须为multipart/form-data method的提交方法必须是post,因为get提交的大小有限制,很小。
  • 然后可以用request.getInputStream()方法获取一个数据流对象:ServletInputStream用于读取上传的对象;也有其他方法获取提交得对象,例如BufferedReader reader = req.getReader();
    上传文件的jsp界面代码

Servlet代码

package com.hjk.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


public class getFile extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletInputStream inputStream = req.getInputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while((len = inputStream.readLine(buffer,0,1024))!=-1){
            String s = new String(buffer,0,len);
            System.out.println(s);
        }
    }
}

这样我们上传一个文件就可以在控制台输出文件里的内容了,应为是用二进制流读取的文件,所以输出的中文会乱码。

我们还要把这些数据写入文件用于保存,这里一般情况下是你根据上传的内容获取文件名字并在项目下创建文件并写入数据,这里我比较懒就随意创建一个写了。把数据写进去。

package com.hjk.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;


public class getFile extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletInputStream inputStream = req.getInputStream();
        File file = new File("D://hello//hello1.txt");
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        byte[] buffer = new byte[102400];
        int len = -1;
        while((len = inputStream.readLine(buffer,0,102400))!=-1){
            String s = new String(buffer,0,len);
            System.out.println(s);
            fileOutputStream.write(buffer,0,len);
        }
    }
}

但是写入的东西,和你原本的内容增加了一起其他的请求头什么的,并且可能还有乱码问题。
现在存在很多的解析器可以让我们处理文件,这里用apche提供的包commons-io-2.11.0.jarcommons-fileupload-1.4.jar
把这两个包导入后,简单写一个处理文件上传的servlet。

package com.hjk.servlet;


import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;


public class getFile extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if(ServletFileUpload.isMultipartContent(req)){ //判断提交的表单是不是分段的,不是分段的不能处理
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();//创建
            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);

            try {
                List fileItems = servletFileUpload.parseRequest(req);
                for (FileItem fileItem : fileItems) {
                    if(fileItem.isFormField()){//如果是不普通文本不处理
                        System.out.println("普通文本");
                    }else{ //处理上传文件
                        File file = new File("D://hello//hello1.txt");//保存文件路径,因为我知道我提交的是txt,这里我直接写死了
                        //在真正开发中在根据实际情况处理
                        fileItem.write(file);//写入文件
                    }
                }

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

文件下载未写

会话管理

在人机交互过程中,会话管理是指保持用户的整个会话活动的交互与计算机系统跟踪的过程。

  • 会话管理可分为桌面会话管理,浏览器会话管理,web会话管理。这里说的是web会话管理,通常是指session和cookie,也称会话跟踪。
  • 会话管理通常以三种方式实现:使用隐藏域,使用Cookie,使用URL重写。

  • 使用隐藏域 我们知道在from表单中的input标签的type可以设置为hidden,value设置为会话的唯一标识,这样页面上既不会展示这个信息,也能随着表单的提交把会话标识上传上去,然后根据这个标识进行处理。例如,我们可以设置一个这样的隐藏域这样就可以把用户id记录下来,每个人有不同的用户id。

    • 这样你必须在你想要的每个页面都要有这样的表单,方法比较繁琐,安全性也差,不适合隐秘性数据。
  • 使用Cookie:Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

  • 使用URL重写:就是指在URL地址的末尾添加会话标识,改写了原先的URL地址,其本质是用唯一标识会话的信息,以参数的形式添加到URL中。

  • Session技术:Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
    Cookie和HttpSession得区别与联系:
    1.Cookie和HttpSession是保存会话相关数据的技术,其中Cookie将信息存储在浏览器端是客户端技术,Session将数据保存在服务器端是服务器端技术;
    2.Cookie是基于HTTP协议中的Set-Cookie响应头和Cookie请求头进行工作的,而默认情况下HttpSession是基于一个名称为JSESSIONID 的特殊Cookie工作的;
    3.浏览器对Cookie具有严格的限制,一个网站能在浏览器中保存多少Cookie是有限制的,而Session没有此限制

过滤器拦截器


过滤器:过滤器能够对目标资源的请求和响应进行截取

  • 只要实现接口Filter的就能实现拦截功能,实现这个接口必须重写三个方法 init(),doFilter(),destroy();
  • 可以处理字符编码,我们不用为每一个请求和响应都去重复设置编码,只需要把所有的请求和响应在这里拦截处理一下,重新设置编码就行了。
  • 可以对用户对象进行检测,我们能不想让没有登录用户直接访问内部的jsp或者Servlt,可以写一个拦截器,凡是没有登录的用户不能直接访问内部的文件。

字符过滤器

package com.hjk.filter;

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

public class CharacterEncoding implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        servletRequest.setCharacterEncoding("utf-8");
        servletRequest.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);//这个方法必须调用,不然会在这里一直拦截,不继续走下去。
    }
    @Override
    public void destroy() {

    }
}

字符过滤器的xml配置


        characterEncoding
        com.hjk.filter.CharacterEncoding
    
    
        characterEncoding
        /*
    
JSP