Jsp&Servlet 「爱情、让人受尽委屈。」 2022-03-26 06:17 249阅读 0赞 ## Servlet ## ## Servlet 的生命周期 ## * 当 servlet 首次被访问时 ,调用构造方法,只调用一次(只有一个servlet对象被创建) * 紧接着调用初始化 init 方法,也是只调用一次 * 根据请求方式,调用 service,或 doGet 或 doPost (请求几次,就会被调用几次) * 当应用程序停止前,调用 destroy 方法,只调用一次 这些方法都是由 tomcat 容器来调用, 这种方式称之为控制反转 Servlet 默认是在第一次访问时被加载,也可以配置服务器启动时被加载 loadOnStartup = 数字 数字代表优先级,数字小的表示优先级高 还可以设置初始化参数(了解) ## Servlet 2.5 以前的版本 ## webapp/WEB-INF/web.xml (部署描述符) 在这里也可以配置servlet中的所有功能,例如: <servlet> <!-- servlet 名字 --> <servlet-name>old</servlet-name> <!-- servlet 对应的 java 类--> <servlet-class>web.OldServlet</servlet-class> <!-- 初始化参数 --> <init-param> <param-name>name</param-name> <param-value>李四</param-value> </init-param> <!-- 让 servlet 在启动时加载,优先级是 3 --> <load-on-startup>3</load-on-startup> </servlet> <servlet-mapping> <!-- servlet 名字, 与上面对应 --> <servlet-name>old</servlet-name> <!-- servlet 访问路径 --> <url-pattern>/old</url-pattern> </servlet-mapping> ### 1. post 请求中的汉字会有乱码问题(重点) ### 原因: String sex = URLEncoder.encode("男", "utf-8"); System.out.println(sex); // iso-8859-1 String result = URLDecoder.decode("%E7%94%B7", "iso-8859-1"); System.out.println(result); // ç”· 解决方法,在调用 getParameter 方法之前: request.setCharacterEncoding("utf-8") ### 2. request 重要方法(重点) ### request.getParameter(“参数名”) => 返回参数值 request.getParameterValues(“参数名”) => 返回参数值的数组 request.getParameterNames(); 取得所有的参数列表 返回一个Enumeration对象 request.getReader() =>取得BufferedReader对象,可以得到<body>中的数据 Enumeration<string> e= req.getParamaterNames(); while(e.hasMoreElements() ){ String param = e.nextElement(); ... } request.setCharacterEncoding(“解码的字符集”); request.getMethod(); ==> 返回请求方式 get, post request.getRequestURI(); ==> 返回当前的请求路径 request.getRemoteAddr(); ==> 获取访问者的ip地址 ### 3. 一个请求分别几个部分(了解) ### GET 两个部分 GET 路径/HTTP 1.1 ==> 请求行 请求头 Host: 要访问那个虚拟主机 一个服务器下有多有 host, 每一个host 下,又有多个应用程序 Accept: 可以处理的内容格式:例如 text/html Accept-Encoding : 能够支持的压缩格式 Accept-Language : 支持的语言, 例如 zh-CN POST 三个部分 Content-Type: 请求体的格式 application/www-form-urlencoded (普通表单格式) Content-Length: 请求体内容的长度 请求体 post的请求参数放入了请求体当中,例如:username=zhangsan&password=123 如果有中文,会自动编码 ### 4. 响应分成3个部分(了解) ### 1. 状态码 * 200 表示响应正确返回 * 404 表示请求的资源不存在 * 500 表示服务器内部出现了异常 * 304 表示该内容没有被修改,那么服务器只会返回状态码和头,不需要返回响应体(图片,html,css,js) * 400 请求参数格式有误. * 403 验证没通过,或权限不足 2. 响应头 * content-type: 响应的内容格式, 例如 text/html;charset=utf8 * content-length: 响应体的长度(字节) * Date: 响应生成时间 3. 响应体 html内容,图片内容 ### 5. 返回一个动态图片(了解) ### 1. 创建图片对象, 构造参数分别代表 宽、高、图片格式 BufferedImage image = new BufferedImage(); 2. 创建画布对象 Graphics2D g = image.createGraphics(); 3. 填充画布 g.setColor(Color.GREEN); g.fillRect(0,0,200,100); 4. 写入文字 g.drawString(s, 0, 32); 5. 把图片内容输出到响应 resp.setContentType(“image/png”); // 参数1 图片对象, 参数2 图片压缩格式 png|jpeg, 参数3: 输出字节流 ImageIO.write(image, “png”, resp.getOutputStream()); // 1. 创建图片对象, 构造参数分别代表 宽、高、图片格式 BufferedImage image = new BufferedImage(200, 100, BufferedImage.TYPE_INT_RGB); // 2. 创建画布对象 Graphics2D g = image.createGraphics(); // 3. 填充画布 g.setColor(Color.GREEN); g.fillRect(0,0,200,100); // 写入文字 g.setColor(Color.BLACK); g.setFont(new Font("微软雅黑", Font.ITALIC, 32)); String s = random(4); g.drawString(s, 0, 32); g.setColor(Color.RED); g.drawLine(0,0,200,100); // 4. 把图片内容输出到响应 resp.setContentType("image/png"); // 参数1 图片对象, 参数2 图片压缩格式 png|jpeg, 参数3: 输出字节流 ImageIO.write(image, "png", resp.getOutputStream()); ### 6.输出二进制字符 ### 使用HTTPServletResponse的getOutputStream()方法取得ServletOutputStream实例。 @WevServlet("/download.do") public class Download extends HttpServlet(HttpServletReuset req, HttpServletResponse resp){ //设置响应内容类型 resp.setContentType("application/pdf"); InputStream in = getServletContext().getResourceAsStream("/WEB-INF/jdbc.pdf"); OutputStream out = resp.getOutputStream(); writeBytes(in,out); private void WriteBytes(InputStream in, OutputStream out){ byte[] buffer = new byte[1024]; int length=-1; while((length=in.read(buffer))!=-1){ out.write(buffer,0,length); } in.close(); out.close(); } } ### 7.取得上传文件 ### request.getPart(“name”)用于取得HTML中file框中上传的文件会返回一个Part对象其中`Con-Disposition:`区段存放了文件的描述信息。 public class UploadServlet extends HttpServlet{ protected void doPost(HttpServletRequest req, HttpServletResponse resp){ Part part = request.getPart("name"); String filename = getFilename(part); //存入文件 part.write(filename); /*取得上传文件名*/ private String getFilename(Prat part){ String header = part.getHeader("Con-Disposition:"); String filename=header.substring(header.indexOf("filename=\"") + 10, header.lastIndexOf("\"") ); return filename; } } } ### 8. 请求转发(重点) ### servlet 中还是用来处理表单请求 跳转至jsp (请求转发) jsp 用来生成html代码并返回 request.getRequestDispatcher("jsp路径").forward(request, response); 如何把servlet中的变量传递给jsp显示 作用域传参 存 request.setAttribute("变量名", 对象); 取(在jsp页面),通过 EL 表达式取 ${ 变量名 } ${ 变量名.属性名 } el 表达式中的属性名,对应着java对象中的 get,set方法名 ## jsp 底层原理 ## 在第一次发送请求时,会把 jsp 文件转义为 java(servlet) 代码,并进一步编译为 class 文件 把页面上的静态内容(html代码),使用 out.write 方法进行打印,其中 out 对应着响应的字符输出流 至于 `<% 代码 %>` 中的代码会原封不动搬移到 jsp 转义生成的 java 代码中 本质仍是一个 servlet ## 旧的生成动态内容的方式 ## 1. `<% 代码 %>` 称为jsp脚本, 其中的变量是方法内的局部变量 2. `<%= 表达式%>` 称为jsp表达式, 用来输出值,不用加;结束 使用jsp表达式获取作用域内容 `<%= request.getAttribute("name") %>` 使用el表达式获取作用域的内容 `${name}` 3. `<%! 代码 %>` jsp的声明, 其中的变量是类的成员变量 4. 注释 `<%-- 注释内容 --%>` 会阻止java代码的运行,包括 jstl 标签和 EL 表达式 都可以使用这种办法注释 5. `<%@ 指令名 %>` * page 用来指明页面的内容类型和编码方式 , isELIgnored=“true|false” 表示是否忽略 EL 表达式 * taglib 用来引入一个标签库 prefix=“前缀” uri=“标签库的标识” * include 用来执行页面的包含操作 <%@ include file="文件路径" %> ## 新的方式 ## jstl 标签 + EL 表达式 (推荐) ## jsp 中的 EL 表达式 ## expression language 主要作用是从作用域中取出变量并显示 request.setAttribute(“变量名”, 值); 页面上可以使用 $\{ 变量名.属性 \} ### 1. 做简单运算 ### <h3>算数运算 ${ 18 + 20 }</h3> <h3>比较运算 ${ 18 > 20 }</h3> <h3>逻辑运算 ${ 18 > 20 and 19 < 30 }</h3> <h3>逻辑运算 ${ 18 > 20 or 19 < 30 }</h3> <h3>逻辑运算 ${ not (18 > 20) }</h3> <h3>三元运算 ${ (false)?"真":"假" }</h3> <h3>空运算 ${ empty names}</h3> ### 2. 用来显示作用域中的变量 (重点) ### * list 显示 可以用 \[下标\] * 要显示大小 list.size() * map 显示 可以用 $\{map.key\} * map 显示 可以用 $\{map\[“key”\]\} * map 显示 可以用 $\{map.get(“key”)\} * 建议map使用字符串作为key,如果非要用整数作为key,必须用 Long, 只能用\[\]语法取,不能用.语法 * 显示java bean, 底层实际调用的是get方法,嵌套的对象可以多次调用.语法 ### 3. 11 个隐式对象 ### * param 代表是请求参数的map集合,用在一个参数有一个值的情况, key对应参数名,value对应参数值 * paramValues 代表是请求参数的map集合,用在一个参数有多个值的情况, key对应参数名,value对应参数值的数组 ### 4. 标准标签库 ### 简称jstl 1. 引入标签库 jar包 <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> 1. 在页面上声明要使用的标签库 <%@ taglib prefix="标签前缀" uri="标签的唯一标识" %> 核心标签 * forEach 进行遍历 <c:forEach items="要遍历的集合" var="临时变量名" begin="起始的下标" end="结束下标" varStatus="保存下标的对象"> </c:forEach> 其中 varStatus 中有两个属性 count(从1开始) , index(从0开始) * if 条件判断 <c:if test="条件">内容</c:if> * choose 条件判断 <c:choose> <c:when test="条件1">内容</c:when> <c:when test="条件2">内容</c:when> <c:when test="条件3">内容</c:when> <c:otherwise>内容</c:otherwise> </c:choose> * format <fmt:formatNumber value="${number}" pattern="¤##,###.##" /> <fmt:formatNumber value="${number}" pattern="00000.00000"/> <fmt:formatDate value="${date}" pattern="yyyy年MM月dd日 HH:mm:ss"/> ## cookie (了解) ## 记住用户名密码这些参数的操作,称之为维护状态(记住这些信息) cookie 本意是小甜点, 在web开发中是用来维系状态的一种技术 服务器要向浏览器返回cookie // 创建cookie Cookie c = new Cookie(名, 值); response.addCookie(c); 浏览器再发送请求时,会把这些cookie值重新发送给服务器 Cookie[] cookies = request.getCookies(); // 遍历 cookies 数组 应用场景: 自动登录、 记录访问网页 ### cookie 的属性 ### maxAge 用来设置 cookie 的寿命, * 默认不设置(-1)表示浏览器关闭寿命就到期 * 指定一个正整数(单位秒),指定cookie存活多久 * 设置为 0,表示由服务器端删除该cookie httpOnly 用来设置是否禁止 js 代码访问 cookie 有安全风险,因为信息是存储在浏览器端的 ## session (重点) ## 把这些状态信息存储在服务器端,安全性要比 cookie 高很多 ### 1. 存储信息 ### // 拿到 session 对象 HttpSession session = request.getSession(); // 存储信息 session.setAttribute("名", 值); ### 2. 获取信息 ### // 拿到 session 对象 HttpSession session = request.getSession(); // 获取信息 session.getAttribute("名"); // 返回上一次存储的值 ### 3. 删除信息 ### session.removeAttribute("名"); // 返回被移除的值 session.invalidate(); // 让session失效(全部清空) 默认生命周期, 第一次调用 request.getSession() 创建 session对象 如果隔了 30 分钟没有向服务器发送请求,session 会自动失效 如果要改变失效时间,可以在 web.xml中: <session-config> <session-timeout>30</session-timeout> </session-config> 跟浏览器的关系:一个浏览器对应服务器端的一个 session 对象 他们存储的信息互不干扰 对比 cookie 和 session * 安全性上, session的安全性高,cookie的信息存在浏览器端所以不安全 * 存储的类型, session 存储的类型是 Object, cookie 只能存字符串(并且需要进行编码处理) * 存储大小, session 理论上没有限制(但不建议存储太多内容), cookie 的限制:每个cookie不能超过4k,每个网站cookie个数也有限制的 * 失效时间, session 两次请求间隔30分钟, cookie 默认关闭浏览器失效,还可以通过 maxAge 调整的更长 ## 请求重定向 (重点) ## 请求转发 request.getRequestDispatcher("跳转路径").forward(request, response); 请求重定向 response.sendRedirect("跳转路径"); 二者的区别 * 请求转发的地址不会改动,始终是刚开始的地址, 请求重定向在跳转后,地址栏会变为目标地址 * 请求转发是一次请求,跳转操作在服务器内部发生;请求重定向是两次请求,跳转操作是在浏览器,服务器之间发生 * 请求转发可以使用 request.setAttribute 进行值的传递;请求重定向需要使用 session.setAttribute 进行值的传递 ## request, session 作用域(scope)对象 (重点) ## 作用范围限于一次请求 request.setAttribute(key, value); request.getAttribute(key) $\{key\} request.removeAttribute(key); 作用范围同一个浏览器的多次请求之间(一次会话) session.setAttribute(key, value); session.getAttribute(key) $\{key\} session.removeAttribute(key); 页面作用域,作用范围限于当前页面 page 应用程序作用域,作用于整个应用程序 application page < request < sesssion < application $\{ key \} 会从小的作用域向大的作用域依次查找,直到找到为止 也可以利用前缀精确地找某个作用域: * pageScope page 作用域 * requestScope 请求作用域 * sessionScope 会话作用域 * applicationScope 应用程序作用域 ## jsp 中的隐式对象 (了解) ## 9 个 * pageContext 页面作用域 * request 请求对象 * session 会话对象 * application 应用程序对象 * response 响应对象 * out 响应输出流 * page 当前的jsp对象(this) * config 用来读取和jsp配置相关的信息 * exception 必须在当前页面的 page 指令中添加 isErrorPage=“true”, 表示一个异常对象 ## 会话跟踪的原理 ## 就是利用 jsessionid 的 cookie 把浏览器和session对象关联起来
相关 详解DefaultServlet与JspServlet -------------------- 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl --- 妖狐艹你老母/ 2022年10月06日 15:56/ 0 赞/ 256 阅读
相关 Jetty9 NO JSP Support for /, did not find org.apache.jasper.servlet.JspServlet 第一次使用Jetty9时,出现的问题 第一次使用Jetty9时,出现的问题 当现在好Jetty9后(可以在官方网站上下载,当前的最新版为Revision 9.1.0- 雨点打透心脏的1/2处/ 2022年09月18日 13:44/ 0 赞/ 362 阅读
还没有评论,来说两句吧...