JavaWeb

Servlet

sun公司开发动态web的一门技术,开发一个Servlet程序有两步:

  • 编写一个类继承Servlet接口
  • 将开发好的Java类部署到服务器上

Servlet接口有两个默认的实现类:HttpServlet和GenericServlet

 

 

 重写doGet()和doPost方法即可,要先导入servlet-api.jar包

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer=resp.getWriter();
        writer.print("Hello!Servlet");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

然后在web.xml中配置servlet映射

  <!--注册Servlet-->
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.deng.HelloServlet</servlet-class>
  </servlet>
  <!--Servlet请求路径映射-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

在Tomcat配置war包并启动Tomcat即可访问

Servlet原理

 

 

 步骤:

  • 浏览器向服务器发出请求
  • 服务器上的容器逻辑接收url,根据url判断为Servlet请求,此时容器逻辑产生两个对象:请求对象(HTTPServletRequest)和响应对象(HttpServletResponse)
  • 容器逻辑根据url找到对应的目标Servlet,并且创建线程,将请求对象和响应对象传给线程
  • 线程调用service()方法,根据请求类型判断是调用doGet()还是调用doPost()
  • doGet()执行完成后,将结果返回给容器逻辑
  • 线程销毁或放到线程池中

ServletContext

web容器启动时,会为每一个web程序创建一个ServletContext对象,代表当前web应用

共享数据

同一个war包中,两个servlet,在HelloServlet里设置ServletContext对象,GetServlet也可以拿到

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        String username="dwx";
        context.setAttribute("username",username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
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");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

获取初始化参数

在web.xml里设置初始化参数

  <context-param>
    <param-name>url</param-name>
    <param-value>www.baidu.com</param-value>
  </context-param>
public class HelloServlet 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);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

实现请求转发

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        context.setAttribute("username","dengwenxiong");
        context.getRequestDispatcher("/getc").forward(req,resp);
    }

读取配置文件

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        InputStream is=context.getResourceAsStream("/WEB-INF/classes/user.properties");//编译后的文件所在的地址
        Properties properties=new Properties();
        properties.load(is);
        String username=properties.getProperty("username");
        String password=properties.getProperty("password");
        resp.getWriter().print(username+":"+password);
    }

 HttpServletResponse

web服务器接收客户端的http请求时,会创建一个代表请求的HttpServletRequest对象和一个代表请求的HttpServletResponse对象

  • 获取客户端请求过来的参数:使用HttpServletRequest
  • 给客户端响应信息:HttpServletResponse

向浏览器发送数据

ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;

下载文件

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //下载文件的路径
        String path="C:\\Users\\邓文( ̄(工) ̄)\\Pictures\\Java语言类型.png";
        //下载的文件名
        String fileName="java.png";
        //设置编码,让其支持中文
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
        //获取下载文件输入流
        FileInputStream fis=new FileInputStream(path);
        //获取输出流
        ServletOutputStream out=resp.getOutputStream();
        //创建缓冲区
        int len=0;
        byte[] buffer=new byte[1024];
        while((len=fis.read(buffer))>0){
            out.write(buffer,0,len);
        }
        fis.close();
        out.close();
    }

生成验证码

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //浏览器三秒刷新一次
       resp.setHeader("refresh","3");
       //在内存中创建一张图片
        BufferedImage image=new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics g=image.getGraphics();
        //设置图片
        g.setColor(Color.white);
        g.fillRect(0,0,80,20);
        //给图片写数据
        g.setColor(Color.BLUE);
        g.setFont(new Font(null,Font.BOLD,20));
        g.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,"jpg",resp.getOutputStream());
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
    private String makeNum(){
        Random random=new Random();
        String num=random.nextInt(9999999)+"";
        StringBuffer stringBuffer=new StringBuffer();
        //保证验证码有七位
        for(int i=0;i<7-num.length();i++){
            stringBuffer.append("0");
        }
        num=stringBuffer.toString()+num;
        return num;

    }
}

实现重定向

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
        resp.sendRedirect("/getc");//重定向
}

HttpServletRequest

HttpServletRequest代表客户端请求,用户通过Http协议访问服务器,Http请求中的所有信息都被封装到HttpServletRequest中,可以通过它获取客户端的所有信息

可以实现请求转发

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/getc").forward(req,resp);
    }

Cookie,Session

Cookie

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //从请求中获取Cookie
        Cookie[] cookies=req.getCookies();
        for (Cookie cookie:cookies) {
            cookie.getName();//获取cookie中的key
            cookie.getValue();//获取cookie中的value
        }
        Cookie cookie1=new Cookie("lastLonginTime",System.currentTimeMillis()+"");//新建Cookie
        cookie1.setMaxAge(60*60);//设置cookie有效期
        resp.addCookie(cookie1);//响应给客户端一个cookie
    }

Cookie一般会保存在本地的用户目录下的appdata里

Cookie的上限:

  • 一个Cookie只能保存一个信息
  • 一个Web站点可以给浏览器发送多个Cookie,最多存放20个
  • Cookie的大小限制在4kb
  • 浏览器的所有Cookie总数限制在300个

删除Cookie:

  • 不设置有效时间,关闭浏览器自动失效
  • 设置有效时间为0

 Session

服务器给每一个用户(浏览器)创建一个Session对象,一个Session独占一个浏览器

Session与Cookie区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存
  • Session是把用户的数据写到Session中,由服务端保存,由服务器创建

使用Session

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到Session
        HttpSession session=req.getSession();
        //在session里存放东西
        session.setAttribute("name","dwx");
        //获取sessionid
        String sessionId=session.getId();
        //判断是否是新建的session
        if(session.isNew()){
            resp.getWriter().print("新的啊"+sessionId);
        }else{
            resp.getWriter().print("旧的"+sessionId);
        }
    }

可以在web.xml里设置会话过期时间

<!--设置Session默认的失效时间-->
<session-config>
     <!--15分钟后Session自动失效,以分钟为单位-->
     <session-timeout>15</session-timeout>
</session-config>

JSP

浏览器向服务器发送请求时,不管访问什么资源,其实都是在访问Servlet

JSP最终也会转换成一个java类,其本质就是一个Servlet

 

 在JSP页面中:

  • java代码就原封不动的输出
  • HTML代码转换为out.write("\r\n");输出到前端

JSP语法格式

<%--注释--%>
<%代码片段%>
<%=表达式%>
<%!声明%>
<%@指令%>

JSP九大内置对象

  • pagecontext
  • request
  • response
  • session
  • application
  • config
  • out
  • page
  • exception
pageContext.setAttribute("name1","秦疆1号"); //保存的数据只在一个页面中有效
request.setAttribute("name2","秦疆2号"); //保存的数据只在一次请求中有效,请求转发会携
带这个数据
session.setAttribute("name3","秦疆3号"); //保存的数据只在一次会话中有效,从打开浏览器
到关闭浏览器
application.setAttribute("name4","秦疆4号"); //保存的数据只在服务器中有效,从打开服
务器到关闭服务器

JSTL标签库

JavaBean

实体类,一般用来个数据库字段做映射ORM(对象关系映射):

  • 表<-->类
  • 字段<-->属性
  • 行记录<-->对象

Filter

过滤器,过滤网站数据

自定义过滤器,实现Filter接口,重写方法

public class ZdyFilter implements Filter {
    //Web服务器启动就已经初始化,等待过滤对象出现
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("自定义的过滤器正在初始化");
    }
    //chain是过滤器链request -> filter1 -> filter2 ->filter3 -> …. -> request resource
    //chain.doFillter()就是将请求转发给过滤器链的下一个过滤器
    @Override
    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("过滤器执行前");
        chain.doFilter(request,response);
        System.out.println("过滤器执行后");
    }
    @Override
    public void destroy() {
        System.out.println("销毁自定义过滤器");

    }
}

在web.xml中配置Filter

  <!--注册过滤器-->
  <filter>
    <filter-name>ZdyFilter</filter-name>
    <filter-class>com.deng.ZdyFilter</filter-class>
  </filter>
  <!--配置映射-->
  <filter-mapping>
    <filter-name>ZdyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

监听器

实现监听器接口(有多种监听器),重写对应方法即可

//统计网站在线人数
public class ZdyListener implements HttpSessionListener {
    //创建Session触发
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext context=se.getSession().getServletContext();
        Integer onlineCount=(Integer) context.getAttribute("OnlineCount");
        if(onlineCount==null){
            onlineCount=new Integer(1);
        }else{
            int count=onlineCount.intValue();
            onlineCount=new Integer(count+1);
        }
        context.setAttribute("OnlineCount",onlineCount);
        System.out.println("在线人数"+onlineCount);
    }
    //销毁Session时触发
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext context=se.getSession().getServletContext();
        Integer onlineCount=(Integer)context.getAttribute("OnlineCount");
        if(onlineCount==null){
            onlineCount=new Integer(0);
        }else{
            int count=onlineCount.intValue();
            onlineCount=new Integer(count-1);
        }
        context.setAttribute("OnlineCount",onlineCount);
        System.out.println("在线人数"+onlineCount);
    }
}

 

在web.xml中注册监听器

 <!--注册监听器-->
  <listener>
    <listener-class>com.deng.ZdyListener</listener-class>
  </listener>

 

posted @ 2021-04-26 14:41  我还有头发  阅读(97)  评论(0编辑  收藏  举报