JavaWeb

JavaWeb

Servlet

编写一个HelloServlet 继承于 HttpServlet
在这里插入图片描述

public class HelloServlet extends HttpServlet{
//根据上图了解,在HelloServlet中我们需要重写HttpServlet中的doGet等方法,因为最常用的是Get 和 Post请求
  @Override
  protected void doGet(HttpServlet req,HttpServlet resp)throws ServletException,IOException{
         PointWrite out = resp.getWriter();
         out.print("hello,servlet");
  
  }
 @Override
  protected void doPost(HttpServlet req,HttpServlet resp)throws ServletException,IOException{
  //post和get的请求逻辑一样,所以可以复用doGet方法
        doGet(req,resp);
  
  }
}

注册servlet,配置servelet映射

<web-app  xmlns="http://xmlns.jcp.org/xml/ns/javaee"                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                                               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"         
version="4.0"        
metadata-complete="true">    
<servlet>    
        <servlet-name>hello</servlet-name>    
        <servlet-class>com.study.servlet.HelloServlet</servlet-class>  
</servlet>  
 <servlet-mapping>    
                <servlet-name>hello</servlet-name>    
                <url-pattern>/hello</url-pattern>  
 </servlet-mapping>
 </web-app>

在这里插入图片描述

Servlet原理

在这里插入图片描述

Mapping问题

一个Servlet可以对应多个mapping
可以自定义路径后缀

<servlet-mapping>  
        <servlet-name>hello</servlet-name> 
        <url-pattern>/hello.do</url-pattern>
</servlet-mapping>

默认请求路径,这样写会无法进入index

<servlet-mapping>
      <servlet-name>helloServlet</servlet-name>
      <url-pattern>/*</url-pattern>
</servlet-mapping> 

错误页面映射,映射路径为/* ,但是如果请求路径为/hello.do依旧会进入HelloServlet,Servlet会优先进入设定好的路径

<servlet>
        <servlet-name>error</servlet-error>
        <servlet-class>com.study.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
          <servlet-name>error</servlet-name>
          <url-pattern>/*<url-pattern>
</servlet-mapping>

ServletContext

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

  • 共享数据
    在helloservlet的context中写入一个数据,在testServlet中获取
public class HelloServlet extends HttpServlet {    
        @Override   
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {        
            ServletContext context = this.getServletContext(); 
            context.setAttribute("username","学习");    }    
}



public class TestServlet extends HttpServlet {    
        @Override    
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {         
        ServletContext context = this.getServletContext();
        String username = (String)context.getAttribute("username");  resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("用户名"+username);    }    
 }
  • 获取初始化参数
<!--        配置web应用初始化参数-->
<context-param>
       <param-name>url</param-name>
       <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
public class DemoServlet extends HttpServlet {    
    @Override    
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {         
    ServletContext context = this.getServletContext(); 
    String url = context.getInitParameter("url"); 
    resp.getWriter().print(url);    }
}
  • 请求转发
    转发:A->B->C
    重定向:A->B B->A A->C
//       转发的请求路径        
context.getRequestDispatcher("/test").forward(req,resp);
  • 读取资源文件
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException {     
        ServletContext context = this.getServletContext();
        InputStream resource = context.getResourceAsStream("/WEB-INF/classes/db.properties");     Properties properties = new Properties();    
        properties.load(resource);     
        String username = properties.getProperty("username");     
        String password = properties.getProperty("password");     resp.getWriter().print(username+":"+password);
        }

可能会出现资源导出问题,需在pom.xml中配置

<!-- 在build中配置resources,来防止导出失败问题 -->
<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

HttpServletResponse

常见应用

  1. 向浏览器发出消息
getWriter()和getOutPutStream
两者的区别:
getWriter 用于发送字符数据
getOutPutStream 用于发送二进制数据

但是两者不能同时使用
原因是servlet会将完成了输出流的response对象给服务器,服务器对response进行解析,会检查流是否关闭,如果没有关闭就会将输出流关闭,当response发现有另一个流被创建,然后尝试进行输出就会发生异常,所以两个流只能使用一个。
  1. 下载文件
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  //获取下载文件路径
  String path = "D:\\JavaWeb\\servlet-02\\target\\classes\\a.1.png";
  System.out.println(path);

  //获取下载文件名
  String filename = path.substring(path.lastIndexOf("\\")+1);
  //设置响应头,让浏览器可以支持下载需要的东西
  resp.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
  //获取下载文件输入流
  FileInputStream in = new FileInputStream(path);
  //创建缓冲区
  byte[] buffer = new byte[1024];
  int len=0;
  //获取输出流
  ServletOutputStream out = resp.getOutputStream();
  //将输出流写入buff缓冲区,使用outputstream将缓冲区的数据输出到客户端
  while((len=(in.read(buffer)))!=-1){
      out.write(buffer,0,len);
  }
  //关闭资源
  out.close();
  in.close();
}
  1. 重定向
    请求A到B, B告诉A要去C 并且还给A ,A再去C
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException {    
            
            /*
            resp.setHeader("Location","/hello");
            resp.setSstatus(302);
            */
        resp.sendRedirect("/hello");
        }

转发时,url地址栏不会发生变化
重定向,url地址栏会发生变化

HttpServletRequest

  1. 获取前端传递的数据
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cqCeNHgo-1640075245133)(en-resource://database/529:1)]
    2.请求转发
req.getRequestDispatcher("/success.jsp").forward(req,resp);

Cookie和Session

会话

用户打开浏览器,点击链接,访问多个web资源,这个过程就叫做会话。
有状态会话:客户端访问服务端,下次再访问的时候服务端知道这个客户端曾经来过

学生如何证明自己是该学校的学生

  1. 发票 学校开的学费发票
  2. 学生名单 学校把学生的名字登记在名单上

同理,网站如何知道一个客户端是否来过

  1. 服务端给客户端一个信件,客户端下次访问的时候带上信件就行,Cookie
  2. 服务端将客户端登记,下次访问时服务端查看是否登记, Session

** 保存会话的两种技术**
cookie 客户端技术(响应,请求)
session 服务器技术,可以保存用户的会话信息,把用户的信息或数据放在Session中,常见场景:网站登录过后,一段时间内再进入该网站不需要重新登录

Cookie

    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {        
    resp.setContentType("text/html");        
    resp.setCharacterEncoding("utf-8");
    //       cookie是服务器给客户端的信件,所以从请求中获取cookie     
    Cookie[] cookies = req.getCookies();
    //        判断cookie是否为空,为空就是第一次来本站       
    if(cookies!=null) {            
    resp.getWriter().print("上一次访问本站的时间");            
    for (Cookie cookie : cookies) 
        {//                获取time的cookie               
            if(cookie.getName().equals("time")){
    //                    得到上一次访问本站的时间,是时间戳                     
                Long value = Long.parseLong(cookie.getValue());
                //                     时间戳转换为时间                     
                Date date = new Date(value); 
                resp.getWriter().print(date.toLocaleString());                
            }           
         }        
    }else{           
            resp.getWriter().print("第一次访问本站");       
    }
    //        设置一个新的时间cookie  时间戳         
    Cookie cookie = new Cookie("time", System.currentTimeMillis() + "");
    //        设置cookie有效时间 单位是s ,不设置有效期,关闭浏览器自动失效,
    //        删除cookie  把有效期设置为0   添加一个同名的cookie来替代它        
    cookie.setMaxAge(24*60*60);
    //        服务端放入新的cookie        
    resp.addCookie(cookie);    
}

中文cookie可能会需要编码和解码

new Cookie("name",URLEncoder.encode("张三","utf-8"));
URLDecoder.decode(cookie.getValue(),"utf-8");

Session(重点)

服务器会给每一个用户(浏览器)创建一个Session对象;
一个Session独占一个卢兰其,只要浏览器没有关闭,这个Session就存在
用户登录之后,整个网站它都可以访问, 比如B站登录之后,可以进入用户管理中心,不登录就无法进入

 @Override    
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {        
                resp.setContentType("text/html");        
                resp.setCharacterEncoding("utf-8");         
                HttpSession session = req.getSession();         
                session.setAttribute("name","张三");         
                String id = session.getId();         
                if(session.isNew()){             
                         resp.getWriter().write("Session创建成功"+id);        
                }else{             
                    resp.getWriter().write("Session已经存在 ");         
                 }
                //         session移除        
                    session.removeAttribute("age");
                //         手动注销session        
                     session.invalidate();    
         }

通常会在web.xml中配置session失效时间,手动注销用于用户手动注销账户,失效时间是自动注销

<session-config>
        <!--    以分钟为单位-->   
        <session-timeout>1</session-timeout>  
</session-config>

Cookie和Session的区别

  • Cookie把用户的数据写给用户的浏览器,存放在客户端,可以存放多个
  • Session是把用户的数据写到用户独占的Session中,存放在服务端,一个浏览器一个Session,一般用来保存重要信息,减少服务器的资源浪费
  • Session对象由服务端创建,虽然是用req.getSession()获取,但是不写这句话依旧存在

JavaBean

实体类,pojo ,entity

  • 属性必须私有
  • 要有无参构造
  • 有对应的get/set方法

用来与数据库做对象关系映射 ORM

过滤器 Filter

  • 处理中文乱码
  • 登陆验证
    在web服务器与Servlet中间加了一层过滤层,过滤垃圾请求
//Filter 是 javax.servlet 包下的
public class CharacterEncoding implements Filter {        
       @Override    
public void init(FilterConfig filterConfig) throwsServletException{      
               System.out.println("过滤器初始化......");    
     }
   @Override
   public void doFilter(ServletRequest request, ServletResponse response, 
FilterChainchain)throwsIOException,ServletException{ 
          response.setCharacterEncoding("utf-8"); 
          response.setContentType("text/html"); 
          System.out.println("过滤器执行中.......");
          // chain 链   让请求继续往下走,可能是下一个过滤器,也可能是servletchain.doFilter(request, response);    }    
          @Override   
          public void destroy() {System.out.println("过滤器销毁......");    }

}

还需要在web.xml中注册,配置映射

<filter>  
       <filter-name>character</filter-name>  
       <filter-class>com.study.filter.CharacterEncoding</filter-class>
</filter>
<filter-mapping>  
       <filter-name>character</filter-name>  
       <url-pattern>/*</url-pattern>
</filter-mapping>

监听器 Listener

public class OnlineListener implements HttpSessionListener {    
@Override//    一旦创建Session 就会触发一次这个事件    
public void sessionCreated(HttpSessionEvent se) {         
        ServletContext context = se.getSession().getServletContext();        
        Integer online = (Integer) context.getAttribute("online");        
        if(online==null){   
                online = 1;       
        }else{   
                int i = online.intValue();  
                online=new Integer(i++);  
        }        
        context.setAttribute("online",online);    
}   
@Override    
public void sessionDestroyed(HttpSessionEvent se) {        
        ServletContext context = se.getSession().getServletContext();       
        Integer online = (Integer) context.getAttribute("online");        
        if(online==null){           
                 online = 0;       
        }else{   
                int i = online.intValue(); 
                online=new Integer(i--);       
        }   
            context.setAttribute("online",online);    }
}

注册监听器

<listener>  
        <listener-class>com.study.linstener.OnlineListener</listener-class>
</listener>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值