Servlet预习和MVC学习笔记

Servlet

1、HttpServlet

  1. 1创建Servlet

  2. 1在web.xml中编写 Servlet的映射

     
        <servlet>
            <servlet-name>helloservlet-name>
            <servlet-class>com.juxiaohei.servlet.Servletservlet-class>
        servlet>
        
        <servlet-mapping>
            <servlet-name>helloservlet-name>
            <url-pattern>hellourl-pattern>
        servlet-mapping>
    

2、ServketContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

2.1、共享数据

我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;

public class Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // this.getInitParameter()  获得初始化参数
        // this.getServletConfig()  获得Servlet配置
        // this.getServletContext() 获得Servlet上下文
        ServletContext context = this.getServletContext();
        String username = "橘小黑";    //数据
        context.setAttribute("username", username);//将一个数据保存在ServletContext中;键值对,通过名称来调用
    }

}
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");  //取出Servlet中setAttribute储存的数据

        resp.setContentType("text/html");	//设置编码格式
        resp.setCharacterEncoding("utf-8");	//设置编码格式
        resp.getWriter().println("名字:"+username);
    }

 <servlet>
        <servlet-name>hellservlet-name>
        <servlet-class>com.juxiaohei.servlet.Servletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>hellservlet-name>
        <url-pattern>/hellurl-pattern>
    servlet-mapping>

    <servlet>
        <servlet-name>getcservlet-name>
        <servlet-class>com.juxiaohei.servlet.GetServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>getcservlet-name>
        <url-pattern>/getcurl-pattern>
    servlet-mapping>

测试访问结果:

2.2、获取初始化参数


   <context-param>
       <param-name>urlparam-name
       >jdbc:mysql://localhost:3306/mybatisparam-value>
   context-param>
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().println("url是:"+url);
    }

2.3、请求转发

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        System.out.println("进入ServletDemo04");
       /* RequestDispatcher requestDispatcher = context.getRequestDispatcher("/s3");  //转发的请求路径
        requestDispatcher.forward(req, resp);//调用forward实现请求转发*/
        context.getRequestDispatcher("/sd3").forward(req, resp);
    }

Servlet预习和MVC学习笔记_第1张图片

2.4、读取资源文件

Properties

  • 在java目录下新建properties
  • 在resources目录下新建properties

发现:都被打包在同一路径下:classes,我们俗称这个路径为classpath;

思路:需要一个文件流;

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properties = new Properties();
        properties.load(is);
        String user = properties.getProperty("username");
        String pwd = properties.getProperty("password");

        resp.getWriter().println(user+":"+pwd);
    }

3、HttpServletResponse

web服务器接收客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequset对象,代表相应的一个HttpServletResponse;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

3.1、简单分类

负责向浏览器发送数据的方法public void setIntHeader(String name, int value);public void addIntHeader(String name, int value);
   public ServletOutputStream getOutputStream() throws IOException;
  public PrintWriter getWriter() throws IOException; 
负责向浏览器发送响应头的方法
  public void setCharacterEncoding(String charset);
  public void setContentLength(int len);
  public void setContentLengthLong(long len);
  public void setContentType(String type);
  public void setDateHeader(String name, long date);
  public void addDateHeader(String name, long date);
  public void setHeader(String name, String value);
  public void addHeader(String name, String value);
  public void addIntHeader(String name, int value);

响应的状态码

    public static final int SC_CONTINUE = 100;

    public static final int SC_SWITCHING_PROTOCOLS = 101;

    public static final int SC_OK = 200;

    public static final int SC_CREATED = 201;

    public static final int SC_ACCEPTED = 202;

    public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;

    public static final int SC_NO_CONTENT = 204;

    public static final int SC_RESET_CONTENT = 205;

    public static final int SC_PARTIAL_CONTENT = 206;

    public static final int SC_MULTIPLE_CHOICES = 300;

    public static final int SC_MOVED_PERMANENTLY = 301;

    public static final int SC_MOVED_TEMPORARILY = 302;

    public static final int SC_FOUND = 302;

    public static final int SC_SEE_OTHER = 303;

    public static final int SC_NOT_MODIFIED = 304;

    public static final int SC_USE_PROXY = 305;

    public static final int SC_TEMPORARY_REDIRECT = 307;

    public static final int SC_BAD_REQUEST = 400;

    public static final int SC_UNAUTHORIZED = 401;

    public static final int SC_PAYMENT_REQUIRED = 402;
     
    public static final int SC_FORBIDDEN = 403;

    public static final int SC_NOT_FOUND = 404;

    public static final int SC_METHOD_NOT_ALLOWED = 405;

    public static final int SC_NOT_ACCEPTABLE = 406;

    public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;

    public static final int SC_REQUEST_TIMEOUT = 408;

    public static final int SC_CONFLICT = 409;

    public static final int SC_GONE = 410;

    public static final int SC_LENGTH_REQUIRED = 411;

    public static final int SC_PRECONDITION_FAILED = 412;

    public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;

    public static final int SC_REQUEST_URI_TOO_LONG = 414;

    public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;

    public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;

    public static final int SC_EXPECTATION_FAILED = 417;

    public static final int SC_INTERNAL_SERVER_ERROR = 500;

    public static final int SC_NOT_IMPLEMENTED = 501;

    public static final int SC_BAD_GATEWAY = 502;

    public static final int SC_SERVICE_UNAVAILABLE = 503;

    public static final int SC_GATEWAY_TIMEOUT = 504;

    public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
}

3.2、常见应用

  1. 向浏览器输出消息
  2. 下载文件
    1. 要获得下载文件的路径
    2. 下载的文件名是什么?
    3. 设置想办法让浏览器能够支持下载我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓冲区
    6. 获取OutputStream对象
    7. 将FileOutputStream流写入到buffer缓冲区
    8. 使用OutputStream将缓冲区的数据输出到客户端!
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 要获得下载文件的路径
        String realPath = "E:\\Code storage\\IDEA\\JavaStudy\\06-Java-Servlet\\target\\classes\\图片下载.png";
        System.out.println("下载文件的路径:"+realPath);
        // 2. 下载的文件名是什么?
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        // 3. 设置想办法让浏览器能够支持下载我们需要的东西
        resp.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName,"utf-8"));
        // 4. 获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
        // 5. 创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        // 6. 获取OutputStream对象
        ServletOutputStream outputStream = resp.getOutputStream();
        // 7. 将FileOutputStream流写入到buffer缓冲区
        while ((len = in.read(buffer)) > 0) {
            System.out.println(buffer.toString());
            outputStream.write(buffer,0,len);
        }
        in.close();
        outputStream.close();
        // 8. 使用OutputStream将缓冲区的数据输出到客户端!
    }

3.3、验证码功能

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如何让浏览器刷新一次
        resp.setHeader("refresh", "3");  //3秒自动刷新一次

        // 在内存中创建一个图片
        BufferedImage image = new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB);

        // 得到图片
        Graphics2D graphics = (Graphics2D) image.getGraphics();
        //设置图片背景颜色
        graphics.setColor(Color.darkGray);
        graphics.fill3DRect(0, 0, 100, 30, true);

        //给图片数据
        graphics.setColor(Color.WHITE);
        graphics.setFont(new Font(null, Font.CENTER_BASELINE, 20));
        graphics.drawString(makeNum(), 0, 20);

        //告诉浏览器这个请求用图片打开
        resp.setContentType("image/jpeg");
        //网站缓存,不让浏览器缓存
        resp.setDateHeader("expires", -1);
        resp.setHeader("Cache-Control", "no-cache");
        resp.setHeader("Pragma", "no-cache");

        //把图片写给浏览器
        ImageIO.write(image, "jpeg",resp.getOutputStream());
    }

    //生成随机数
    private String makeNum() {
        Random random = new Random();
        String num = random.nextInt(999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 6 - num.length(); i++) {
            sb.append("0");
        }
        num = sb.toString()+"   " + num;
        return num;
    }

3.4、实现重定向

Servlet预习和MVC学习笔记_第2张图片

一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /* //重定向方式二
        resp.setHeader("Location","/r/img")		//跳转地址
         resp.setStatus(302);	//设置一个状态码
        */
        resp.sendRedirect("/r/img");	//重定向
        
    }

面试点:请你聊聊重定向和转发的区别?

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候,url不会产生变化
  • 重定向时候,url地址栏会发生变化
  • 转发可以携带数据
  • 重定向无法携带数据

4、HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息都会被封装到HttpServletRequest,通过这个HttpServletRequest的方法获得客户端的所有信息;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5qi5qmmF-1614846639419)(C:\Users\39774\AppData\Roaming\Typora\typora-user-images\image-20210225134708875.png)]

4.1、获取前端传递的参数

Servlet预习和MVC学习笔记_第3张图片

4.2、请求转发

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("").forward(request,response);
    }

5、Cookie、Sessin

5.1、会话

**会话:**用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话;

一个网站,怎么证明你来过?

客户端 服务端

  1. 服务端给客户端一个新建,客户端下次访问服务端带上信件就可以了;Cookie
  2. 服务器登记你来过了,下次你来的时候我匹配你;Session

5.2、保存会话的两种技术

cookie

  • 客户端技术(响应,请求)

session

  • 服务器技术,利用这个技术可以保存用户的会话信息。我们可以把信息或者数据放在Session中;

解决中文乱码问题:

  //解决乱码问题
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

5.3、Cookie

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
//Cookie,服务器端从客户端获取
	Cookie[] cookies = request.getCookies();//这里返回数组,说明Cookie可能存在多个
	cookie.getName();//获得cookie中的key
	cookie.getValue();//获得cookie中的value
	new Cookie("lastLoginTime", System.currentTimeMillis() + "");//新建一个cookie
	cookie.setMaxAge(24*60*60);//设置cookie的有效期
	response.addCookie(cookie);//响应给客户端一个cookie

cookie:一般会保存在本地的 用户目录下 aoodata;

一个网站cookie是否存在上限?

  • 一个Cookie只能保存一个信息;
  • 一个web站点可以给浏览器发送多个cookie,最多存放20个;
  • Cooie大小有限制4kb;
  • 300个cookie浏览器上限

删除Cookie:

  • 不设置有效期,滚逼浏览器,自动失效;
  • 设置有效期时间为0;

5.4、Session(重点)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AlezzEGI-1614846639422)(C:\Users\39774\AppData\Roaming\Typora\typora-user-images\image-20210225152658609.png)]

什么是Session:

  • 服务器会给每一个用户(浏览器)创建一个Session对象;
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
  • 用户登陆之后,整个网站都可以访问;–>保存用户的信息

存储一个Session数据:

		//得到Session
        HttpSession session = req.getSession();
        //给Session中存东西
        session.setAttribute("name", new Person("橘小黑",21));	//new Person("橘小黑",21);这是一个类的有参构造函数
        //获取Session的ID
        String id = session.getId();
        //判断Session是不是新创建
        if (session.isNew()) {
            resp.getWriter().write("session创建成功,ID:"+id);
        } else {
            resp.getWriter().write("Session已经在服务器中存在了,ID:"+id );
        }

得到Session中的数据:

 		//得到Session
        HttpSession session = req.getSession();
        //取出Session中存东西
        Person person = (Person) session.getAttribute("name");
        System.out.println(person.toString());

手动注销Session:---->invalidate()方法

  HttpSession session = req.getSession();
        session.removeAttribute("name");
        //手动注销Session
        session.invalidate();

自动失效:----->在web.xml中


    <session-config>
        
        <session-timeout>1session-timeout>
    session-config>

Session和Cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个);
  • Session把用户的数据写到用户独占的Session中,服务端保存(保存重要的信息,减少服务器资源的浪费);
  • Session是由服务器创建;

6、JSP九大内置对象

  • OageContext ------>存东西
  • Request ------>存东西
  • Response
  • Session ------>存东西
  • Application 【ServletContext】 ------>存东西
  • config 【ServletConfig】
  • out
  • page
  • excepetion

7、MVC三层架构

什么是MVC: Model view Controller 模型、视图、控制器;

7.1早些年

Servlet预习和MVC学习笔记_第4张图片

用户直接访问控制层,控制层就可以直接操作数据库;

servlet--CRUD-->是数据库
    弊端:程序十分臃肿,不利于维护
        servlet的代码中:代理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
架构:没有什么是加一层解决不了的!
程序员
|
JDBC
|
Mysql oracle SqlServer

7.2、三层架构

Servlet预习和MVC学习笔记_第5张图片

Model

  • 业务处理:业务逻辑层(Service)
  • 数据持久层:CRUD(Dao)

View

  • 展示数据
  • 提供链接发起Servler请求 (a,form,img…)

Controller (Servlet)

  • 接受用户的请求:(req:请求参数、Session信息…)
  • 交给业务层处理对应的代码
  • 控制视图的跳转
登陆--->接收用户的登录请求--->处理用户的请求(获取登陆用户的参数)--->交给业务层处理登陆业务--->Dao曾查询用户名和密码是否正确--->数据库

8、过滤器(Filter)

Filter:过滤器,用来过滤网站的数据;

  • 处理中文乱码
  • 登陆验证…

Servlet预习和MVC学习笔记_第6张图片

Filter开发步骤:

  1. 导包

  2. 编写过滤器

    1. 导包不要错:javax.servlet.Filrer

    2. 实现Filter接口,实现重写方法

      public class CharacterEncodingFilter implements Filter {
          // 初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现;
          public void init(FilterConfig filterConfig) throws ServletException {
              System.out.println("CharacterEncodingFilter初始化");
          }
      
          /*
              Chain:链
              1.过滤中的所有代码,在过滤特定的请求的时候都会执行
              2.必须要让过滤器同行
                  chain.doFilter(request,response);
           */
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              request.setCharacterEncoding("utf-8");
              response.setCharacterEncoding("utf-8");
              response.setContentType("text/html;charset=utf-8");
              System.out.println("CharacterEncodingFilter执行前...");
              chain.doFilter(request, response);   //让我们的请求继续走,如果不屑,程序奥这里就被拦截停止
              System.out.println("CharacterEncodingFilter执行后...");
          }
      
          // 销毁:web服务器关闭的时候,过滤器会销毁
          public void destroy () {
              System.out.println("CharacterEncodingFilter销毁");
          }
      }
      
    3. 在web.xml中配置Filter

       
          <filter>
              <filter-name>CharacterEncodingFilterfilter-name>
              <filter-class>com.juxiaohei.filter.CharacterEncodingFilterfilter-class>
          filter>
          <filter-mapping>
              <filter-name>CharacterEncodingFilterfilter-name>
              
              <url-pattern>/s
      

你可能感兴趣的:(学习笔记分享,servlet,springmvc,java,session,cookie)