栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

新职课(chapter5-2)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

新职课(chapter5-2)

文章目录
  • Servlet
    • API
    • 生命周期
    • Request
    • Response
    • 会话
    • 初始化参数
    • 注解
  • JSP
    • 内置对象
    • 指令
    • 常见状态码
    • EL表达式
    • JSTL

Servlet
  • Servlet(Server Applet)
  • 作用:是⽤Java编写的服务器端程序,扩展基于HTTP协议的Web服务器
    • 说成人话就是:运行于tomcat这样的应用服务器之上的处理web请求的类(接口),实现请求与处理的衔接
    • tomcat + Servlet 提供了JavaWeb的运行环境,类似Python中的UWSGI服务器,实现路由
  • 工作流程
    • 客户端发送请求⾄服务器
    • 服务器启动并调⽤Servlet,Servlet根据客户端请求⽣成响应内容(调用我们自定义的逻辑)并将其传给服务器
    • 服务器将响应返回客户端
API
  • Servlet是接口,需要实现;关系如图:
  • 使用需要导入 javaee-api-7.0.jar,注意scope
  • 继承和实现都可以
    // 业务逻辑类最终都是要通过这两个方方式调用的嘛
    public class ServletTest extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        	// 业务逻辑
            System.out.println("get---------");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        	// 业务逻辑
            System.out.println("post----------");
        }
    }
    
  • 如何验证,我们用到了实现的servlet,处理前端的请求?要用到WEB-INF/web.xml
    
    
    
        
            demo
            
                web.ServletTest
            
        
    
        
            demo
            /test
        
    
    
    • mapping中匹配到路径,就到servlet标签中找逻辑类,调用我们重写的 get/post 方法
    • flask用装饰器路由到处理方法,并限定请求方法;这里用xml映射和servlet类的请求方法包裹处理方法
    • 总之:都完成了路由和限定请求方法的作用
生命周期
  • 四个过程
    • 实例化 --先创建servlet实例
    • 初始化 --init()
    • 处理请求 --service(),即doGet/doPost方法(先调用父类的service())
    • 服务终⽌ --destory()
  • ⽤户发送第⼆次请求时,会判断servlet对象是否存在,但不再执⾏init(),直接执⾏ service ⽅法
Request
  • HttpServletRequest 表示Http环境中的Servlet请求。它扩展于 javax.servlet.ServletRequest 接⼝
  • 更改一下业务逻辑,使用 req 获取参数 getParameter()
    public class ServletTest extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 业务逻辑
            System.out.println("get---------");
            String username = req.getParameter("username");
            String userage = req.getParameter("userage");
            System.out.println(username+"----"+userage);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 业务逻辑
            System.out.println("post----------");
            req.setCharacterEncoding("utf-8");
            String username = req.getParameter("username");
            System.out.println(username);
        }
    }
    
  • get请求不需要指定编码,post请求需要指定
  • 更改代码后需要重启tomcat应用服务器
  • 无论前端使用什么格式传递,后端都用 String 接收,也可以指定跳转到某个页面(redirect)
    @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 业务逻辑
        System.out.println("post----------");
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        System.out.println(username);
        String[] hobbyes = req.getParameterValues("hobby");
        for (String hobby : hobbyes) {
            System.out.println(hobby);
        }
        req.getRequestDispatcher("/index.html").forward(req,resp);  // 这个根目录就是web
    }
    
  • 在单次请求中,可以存值取值
    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 业务逻辑
        System.out.println("get---------");
        String username = req.getParameter("username");
        String userage = req.getParameter("userage");
        System.out.println(username+"----"+userage);
    
        req.setAttribute("usersex", "man");
        Object sex = req.getAttribute("usersex");
        System.out.println(sex);
    
        req.getRequestDispatcher("/index.html").forward(req,resp);
    }
    
    
    
    
        
        demo
    
    
        

    this is demo for servlet

    servlet impl
    username: hobby: 篮球 排球 足球
Response
  • 目前能看到效果的就是redirect方法
    // req.getRequestDispatcher("/index.html").forward(req,resp);
    resp.sendRedirect("/index.html");
    
  • 转发和重定向的区别是什么呢?重定向第一次只返回页面的路径,会再次请求(地址栏修改了两次)
    • 转发会直接返回路由路径
会话
  • request存的值只能在单次请求中保存,保存的数据不能跨⻚⾯,当重定向时,request存的值会丢失
  • 会话:从打开浏览器到关闭浏览器,期间访问服务器就称为⼀次会话
  • session的数据可以在多个⻚⾯中共享
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 业务逻辑
        System.out.println("get---------");
    
        // session
        HttpSession session = req.getSession();
        session.setAttribute("name", "roy");
        session.getAttribute("name");
        String sid = session.getId();
        System.out.println(sid);    // 520A40F0E0F2022B809BAC62D0579C5D
    
        resp.sendRedirect("/index.html");
    }
    
初始化参数
  • 分全局和局部初始化参数,编写两个业务类测试一下,对应的xml
    
    
        
            param_g
            allen~
        
    
        
            demo
            
                web.ServletTest
            
            
            
                param_l
                roy~
            
        
    
        
            demo
            /test
        
    
        
            demo2
            
                web.ServletParam
            
        
    
        
            demo2
            /test2
        
    
    
    public class ServletTest extends HttpServlet {
        @Override
        public void init(ServletConfig config) throws ServletException {
            System.out.println(config.getInitParameter("param_l")); // local param
            System.out.println(config.getServletContext().getInitParameter("param_g")); // global init param
        }
    }
    
    public class ServletParam extends HttpServlet {
        @Override
        public void init(ServletConfig config) throws ServletException {
            System.out.println(config.getInitParameter("param_l")); // local param
            System.out.println(config.getServletContext().getInitParameter("param_g")); // global init param
        }
    }
    
注解
  • 使用注解的方式实现Servlet,不使用xml文件映射;更像Python装饰器了
    @WebServlet(urlPatterns = {"/test/stu", "/test/student"}, name="stu", initParams = {
            @WebInitParam(name = "stu-param", value = "stu-value")
    }, loadonStartup = 1)	// 值越小,优先级越高
    public class Student extends HttpServlet {
        @Override
        public void init(ServletConfig config) throws ServletException {
            System.out.println("stu servlet: " + config.getInitParameter("stu-param"));
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("get");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
    
JSP
  • Java Server Pages,其根本是⼀个简化的Servlet设计,底层还是servlet
  • JSP就是在HTML⻚⾯中嵌⼊了java代码,得到 .jsp 动态页面(应以HTML为主)
    • 使用小脚本嵌入Java代码
    <%!变量或者⽅法声明%>	// 声明标签
    <%= 表达式%>			// 表达式标签
    <%java代码%>			// 程序代码标签
    
  • 看个例子,这里要用到 jasper-6.0.29.jar
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    	<%! int i=10;%>		
    	<%! public void show(){}%> 
    	<%=i%> 	
    
    
  • 原理
    • 根据路径找到index.jsp⽂件
    • 翻译成index_jsp.java⽂件
    • 进⾏编译,产⽣⼀个index_jsp.class⽂件,加载运⾏
  • HTML代码最终以流的形式翻译输出到class,再写回浏览器(out.Writer()),这期间动态的换上了Java逻辑要输出的内容
    • 查看生成的 .java 文件会发现继承了HttpServlet
内置对象
  • 面试必考,有九个分别为:request、response、session、application、out、 pagecontext、config、page、exception
  • 建立两个页面测试一下下面四个对象的作用域:
    // index.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
      
        $Title$
      
      
        <%  // 单次请求期间,通过index2.jsp访问就会变成null
            request.setAttribute("a",10); %>
        request: <%= request.getAttribute("a") %>
    
        <%  // 一次浏览器会话期间
            session.setAttribute("b", 11);
        %>
        session: <%= session.getAttribute("b")%>
    
        <%  // 整个程序运行期间,换了浏览器也行
            application.setAttribute("c", 12);
        %>
        appliaction: <%= application.getAttribute("c") %>
    
        <%  // 当前页面, page = java this 可以获取当前页面的java对象
            pageContext.setAttribute("d", 13);
        %>
        page: <%= pageContext.getAttribute("d") %>
      
    
    
    // index2.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        index2.jsp
    
    
        request: <%= request.getAttribute("a") %>
    
        session: <%= session.getAttribute("b")%>
    
        application: <%= application.getAttribute("c") %>
    
        page: <%= pageContext.getAttribute("d") %>
    
    
    
    • 换了浏览器application的值仍然可以get到
  • 可以指定404页面(errorPage)
    // index.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="index2.jsp" %>
    // 制造异常
    out: <% out.print(6/0);%>
    
    // index2.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
    errorMSG: <%=exception.getMessage() %>
    
指令
  • JSP指令⽤来设置整个JSP⻚⾯相关的属性,有三个
  • 可以包含多个page指令,<%@ page attribute="value" %>
  • include可以传入相对路径:<%@ include file="⽂件 url 地址" %>
  • 将JSTL时会详细介绍标签库taglib
常见状态码
  • 提升调错能力
EL表达式
  • 之前使用小脚本的方式,把HTML代码和Java代码混着写,这样好吗?这样不好,容易傻
  • 于是有了EL(expression language),用于展示数据,jsp中使用${ },包括的基础操作符:
  • 来个例子看看,只能识别作用域中的变量,就是那几个内置对象设置的变量才行
    <%@ page import="java.util.List" %>
    <%@ page import="java.util.ArrayList" %>
    <%@ page import="java.util.Map" %>
    <%@ page import="java.util.HashMap" %><%--
      Created by IntelliJ IDEA.
      User: Windows10
      Date: 2021/12/28
      Time: 14:57
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
    
    
        index2.jsp
    
    
        <%
            request.setAttribute("p1", 15);
    
            List list = new ArrayList();
            list.add(18);
            pageContext.setAttribute("p2", list);
    
            Map map = new HashMap();
            map.put("m1", 66);
            application.setAttribute("p3", map);
        %>
        ${10+20}
    p1: ${p1}
    list: ${p2[0]}
    map: ${p3.m1}
  • 如果内置对象设置的变量名冲突了呢?默认从小到大找:pageContext < request < session < application
JSTL
  • EL最初定义于JSTL1.0部分,JSP2.0之后将其搞出来成为了JSP的一部分
  • JSTL就是封装了EL的标签库,让我们更方便的使用EL,而定义的一些标签,更加简化jsp⻚⾯的编写
    • 比如EL取集合的值只能逐个写标签,不能循环取值
  • 按功能分五部分:分别是 :核⼼标签 格式化标签 sql标签 xml标签 jstl函数
  • 使用:jakarta-taglibs-standard-1.1.2/lib/ 下的两个 jar ⽂件:standard.jar 和 jstl.jar ⽂件拷⻉到 /WEB-INF/lib/ 下
    • taglibs是JSTL的具体实现,所以下载的话还是taglibs,里面包含了jstl和standard,别搞混
  • 核⼼标签是最常⽤的 JSTL标签,看个例子
    <%@ page import="java.util.List" %>
    <%@ page import="java.util.ArrayList" %>
    <%@ page import="java.util.Date" %><%--
      Created by IntelliJ IDEA.
      User: Windows10
      Date: 2021/12/28
      Time: 21:12
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    
    
        Title
    
    
        

    JSTL

    ${name} <%--一般使用上面的EL表达式直接输出--%> <%--分支 --%> this is roy. <%--多分支--%> this is allen. this is roy. <% List list = new ArrayList(); list.add(18); list.add(20); pageContext.setAttribute("list", list); %> <%--循环结果--%> ${stat.count}---${stat.index}: ${id}
    <%--i18n--%> <% pageContext.setAttribute("time", new Date()); %>
    • 比较常用的还有fmt:formatDate
  • OK!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/683778.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号