导学

在之前的学习中,我们已经初步认识到什么是Servlet和Jsp。那么今天我们再来重新认识一下Servlet和Jsp,本节课需要掌握Java Web的核心特性(请求与响应的结构)、掌握Servlet的核心对象、Jsp九大内置对象(面试笔试中常遇到)等内容

HTTP请求的结构

请求是浏览器像服务器发送的数据包,那么在请求中其实是包含了三部分的内容的:请求行,请求头,请求体。
4.Servlet与Jsp进阶 - 图1
请求行包括请求的方式,请求的地址,以及请求的HTTP版本
请求头中,包括很多辅助的请求信息,能为请求处理提供额外的支持。
资料(关于请求头与响应头):https://www.cnblogs.com/xjcjcsy/p/6135006.html
请求体中,描述了请求的参数内容。注意一下,get请求是将参数写入URL中,所以get请求是没有请求体的,只有post请求才有请求体。

  1. /**
  2. * Servlet implementation class MethodServlet
  3. */
  4. @WebServlet("/method")
  5. public class MethodServlet extends HttpServlet {
  6. private static final long serialVersionUID = 1L;
  7. /**
  8. * @see HttpServlet#HttpServlet()
  9. */
  10. public MethodServlet() {
  11. super();
  12. // TODO Auto-generated constructor stub
  13. }
  14. /**
  15. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  16. */
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. response.getWriter().println("This is Get method");
  19. }
  20. /**
  21. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  22. */
  23. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  24. response.getWriter().println("This is Post method");
  25. }
  26. }
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Insert title here</title>
  6. </head>
  7. <body>
  8. <form action="/MyJsp/method" method="get">
  9. <input name="userName"/>
  10. <input name="password" type="password"/>
  11. <input type="submit"/>
  12. </form>
  13. </body>
  14. </html>

4.Servlet与Jsp进阶 - 图2
4.Servlet与Jsp进阶 - 图3

利用请求头开发多端应用

早期的程序,基本都是运行的在电脑上的,我们编写页面的时候只要考虑电脑端的情况就可以了。但是随着个人设备越来越多,我们需要考虑的显示设备也越来越多,那么我们该如何去尝试着在Java中进行多种设备的考量呢?这个时候我们就可以利用请求头进行判断分析

  1. /**
  2. * Servlet implementation class UserAgentServlet
  3. */
  4. @WebServlet("/useragent")
  5. public class UserAgentServlet extends HttpServlet {
  6. private static final long serialVersionUID = 1L;
  7. /**
  8. * @see HttpServlet#HttpServlet()
  9. */
  10. public UserAgentServlet() {
  11. super();
  12. // TODO Auto-generated constructor stub
  13. }
  14. /**
  15. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  16. */
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. String userAgent = request.getHeader("User-Agent");//获取请求头信息
  19. response.setContentType("text/html;charset=utf-8");//设置服务器端响应的编码方式以及内容解析方式
  20. response.getWriter().println(userAgent);
  21. String output = "";
  22. if(userAgent.indexOf("Windows NT") != -1) {
  23. output = "<h1>这是PC端</h1>";
  24. } else if(userAgent.indexOf("iPhone") != -1 ||userAgent.indexOf("Android") != -1 ){
  25. output = "<h1>这是手机端</h1>";
  26. }
  27. response.getWriter().println(output);
  28. }
  29. /**
  30. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  31. */
  32. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  33. }
  34. }

响应的结构

HTTP响应包含三部分:响应行、响应头、响应体
4.Servlet与Jsp进阶 - 图4
HTTP常用状态码:
4.Servlet与Jsp进阶 - 图5

ContentType的作用

ContentType决定浏览器采用何种的方式对响应体进行处理。
4.Servlet与Jsp进阶 - 图6

  1. /**
  2. * Servlet implementation class ContentTypeServlet
  3. */
  4. @WebServlet("/contenttype")
  5. public class ContentTypeServlet extends HttpServlet {
  6. private static final long serialVersionUID = 1L;
  7. /**
  8. * @see HttpServlet#HttpServlet()
  9. */
  10. public ContentTypeServlet() {
  11. super();
  12. // TODO Auto-generated constructor stub
  13. }
  14. /**
  15. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  16. */
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. String output = "<h1><a href='www.baidu.com'><span>百度</span></a></h1>";
  19. /*response.setContentType("text/html;charset=utf-8");*/
  20. /*response.setContentType("text/plain;charset=utf-8");*///输出纯文本
  21. /*response.setContentType("text/xml;charset=utf-8");*/
  22. response.setContentType("application/x-msdownload;charset=utf-8");
  23. response.getWriter().println(output);
  24. }
  25. /**
  26. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  27. */
  28. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  29. }
  30. }

请求转发与重定向

在之前的学习中,都是通过一个servlet来完成的程序处理,但在真正的开发中,需要多个servlet进行组合调用。从A servlet到B servlet,完成一场“传值的游戏”。那么从A到B之间,如何进行通信和跳转呢?
对于多个servlet和jsp之间跳转有两钟方式:

  1. 请求转发:request.getRequestDispatcher(path).forward(request,response)
  2. 响应重定向:response.sendRedirect(Contextpath工程名称/映射地址);
    区别:
    请求转发是不会改变一开始访问的映射地址
    响应重定向是会改变到最后请求的映射地址

    请求转发与重定向的使用

    1. @WebServlet("/direct/index")
    2. public class IndexServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public IndexServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. response.getWriter().println("This is index page");
    9. }
    10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    11. }
    12. }
    1. /**
    2. * 用户校验页面
    3. * @author LiXinRong
    4. *
    5. */
    6. @WebServlet("/direct/check")
    7. public class CheckLoginServlet extends HttpServlet {
    8. private static final long serialVersionUID = 1L;
    9. public CheckLoginServlet() {
    10. super();
    11. }
    12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13. System.out.println("用户登录成功");
    14. //请求.请求触发器.转发->浏览器地址栏不会发生改变
    15. request.getRequestDispatcher("/direct/index").forward(request, response);
    16. //响应重定向需要增加contextPath->浏览器地址栏会发生改变
    17. response.sendRedirect("/sd/direct/index");
    18. }
    19. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    20. }
    21. }

    转发时,是在服务器内部由第一个servlet跳转到新的servlet。而转发是在服务器处理完第一个servlet后,通知浏览器,由浏览器再发送一个请求给服务器的新的servlet。

    请求转发与重定向的原理

    虽然请求转发与重定向都是用于地址的跳转,但是它们两个在本质上是完全不一样的。
    请求转发
    请求转发:request.getRequestDispatcher(path).forward(request,response)
    请求转发是在服务器内部进行跳转,转发调用的是HttpServletRequest对象中的方法以及转发时浏览器只请求一次服务器,地址栏的url不会发生变化。
    4.Servlet与Jsp进阶 - 图7
    在进行请求转发时,允许创建自定义属性。
    设置请求属性:
    request.setAttribute(属性名,属性值)
    获取请求属性:
    Object attr = request.getAttribute(属性名)

    1. @WebServlet("/direct/check")
    2. public class CheckLoginServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public CheckLoginServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. System.out.println("用户登录成功");
    9. request.setAttribute("name", "Jack");
    10. //请求.请求触发器.转发->浏览器地址栏不会发生改变
    11. request.getRequestDispatcher("/direct/index").forward(request, response);
    12. //响应重定向需要增加contextPath
    13. /*response.sendRedirect("/sd/direct/index");*/
    14. }
    15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16. }
    17. }

    image.pngimage.png

    1. @WebServlet("/direct/index")
    2. public class IndexServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public IndexServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. String name = (String)request.getAttribute("name");
    9. System.out.println(name);
    10. System.out.println("index page");
    11. request.getRequestDispatcher("/direct/index2").forward(request, response);
    12. }
    13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. }
    15. }
    1. @WebServlet("/direct/index2")
    2. public class IndexServlet2 extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public IndexServlet2() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. String name = (String)request.getAttribute("name");
    9. System.out.println(name);
    10. System.out.println("index page2");
    11. request.getRequestDispatcher("/direct/index3").forward(request, response);
    12. }
    13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. }
    15. }
    1. @WebServlet("/direct/index3")
    2. public class IndexServlet3 extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public IndexServlet3() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. String name = (String)request.getAttribute("name");
    9. System.out.println(name);
    10. System.out.println("index page3");
    11. }
    12. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13. }
    14. }

    在servlet中定义的属性,可以通过请求转发一直传递下去。
    重定向
    响应重定向:response.sendRedirect(Contextpath工程名称/映射地址);
    重定向则是浏览器端跳转,会产生两次请求。
    4.Servlet与Jsp进阶 - 图10
    重定向的时候不会去传递属性。
    注意:

  3. 如果需要携带数据到要跳转的界面,建议使用转发。地址栏不会改变。

  4. 如果不需要携带数据到要跳转的界面,建议使用重定向。地址栏会改变

    Cookie与Session

    Cookie

    Cookie(小甜饼)是浏览器保存在本地的文本内容,cookie常用于保存登录状态,用户资料等小文本。cookie是具有时效性的,有效的cookie内容会伴随着请求发送给Tomcat。比如我们可以使用cookie保存用户的登录信息,这样在一定时长内,用户就可以一直保持登录状态了。
    4.Servlet与Jsp进阶 - 图11
    该文件打开是一堆乱码,这是因为这个文件往往包含敏感数据,所以浏览器对此进行了加密。
    4.Servlet与Jsp进阶 - 图12
    设置Cookie

    1. @WebServlet("/cookies/lg")
    2. public class LoginServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public LoginServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. System.out.println("用户登录成功");
    9. //设置用户七天内保持登录
    10. Cookie cookie = new Cookie("user","admin");
    11. cookie.setMaxAge(60*60*24*7);
    12. response.addCookie(cookie);
    13. response.getWriter().println("login success");
    14. }
    15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16. }
    17. }

    setMaxAge(time) : 设置Cookie最大有效期,单位 s
    若不设置有效期,则cookie有效期为当前浏览器窗口,若窗口关闭,则cookie清空

4.Servlet与Jsp进阶 - 图13
读取cookie

  1. @WebServlet("/cookies/is")
  2. public class IndexServlet extends HttpServlet {
  3. private static final long serialVersionUID = 1L;
  4. public IndexServlet() {
  5. super();
  6. // TODO Auto-generated constructor stub
  7. }
  8. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  9. Cookie[] cs = request.getCookies();//用于获取所用的用户信息
  10. if(cs == null){
  11. response.getWriter().println("user not login");
  12. return;
  13. }
  14. String user = null;
  15. for(Cookie c :cs) {
  16. System.out.println(c.getName() + ":" + c.getValue());
  17. if(c.getName().equals("user")) {
  18. user = c.getValue();
  19. break;
  20. }
  21. }
  22. if(user == null) {
  23. response.getWriter().println("user not login");
  24. } else {
  25. response.getWriter().println("user:" + user);
  26. }
  27. }
  28. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  29. doGet(request, response);
  30. }
  31. }

注意cookie是作用于本目录及其子目录,如果发送cookis那个文件的映射地址是/cookies/login,那么想要获取的那个也必须是/cookies/xx

  1. @WebServlet("/cookie/is")//该地址获取不到对应的cookie
  2. public class IndexServlet2 extends HttpServlet {
  3. private static final long serialVersionUID = 1L;
  4. public IndexServlet2() {
  5. super();
  6. }
  7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  8. Cookie[] cs = request.getCookies();//用于获取所用的用户信息
  9. String user = null;
  10. for(Cookie c :cs) {
  11. System.out.println(c.getName() + ":" + c.getValue());
  12. if(c.getName().equals("user")) {
  13. user = c.getValue();
  14. break;
  15. }
  16. }
  17. if(user == null) {
  18. response.getWriter().println("user not login");
  19. } else {
  20. response.getWriter().println("user:" + user);
  21. }
  22. }
  23. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  24. doGet(request, response);
  25. }
  26. }

session

cookie是保存在我们本地的数据,但是这个数据不一定可靠,保存在本地迟早会被破解,而且设置cookie之后,每次发送请求都会携带cookie,增加了浏览器的带宽负担。于是,我们有了一个新的解决方案session,用于将数据保存在服务器上。
session特点:

  1. Session(用户会话)用于保存”浏览器窗口”对应的数据
  2. Session的数据存储在Tomcat服务器的内存中,具有时效性(无人访问时长为30分钟)
  3. Session通过浏览器Cookie的Session Id(浏览器的session识别码)值提取用户数据,每个浏览器的Session Id都不一样。

    1. @WebServlet("/session/sl")
    2. public class SessionLoginServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public SessionLoginServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. System.out.println("用户登录成功");
    9. //获取用户会话session对象
    10. HttpSession session = request.getSession();
    11. session.setAttribute("name", "张三");
    12. String sessionId = session.getId();
    13. System.out.println(sessionId);
    14. request.getRequestDispatcher("/session/id").forward(request,response);
    15. }
    16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. doGet(request, response);
    18. }
    19. }
    1. @WebServlet("/session/sil")
    2. public class SessionIndexServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public SessionIndexServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. HttpSession session = request.getSession();
    9. String sessionId = session.getId();
    10. System.out.println(sessionId);
    11. String name = (String)session.getAttribute("name");
    12. response.setContentType("text/html;charset=utf-8");//设置返回内容解码方式
    13. response.getWriter().println("这是首页,当前用户为:" + name);
    14. }
    15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16. doGet(request, response);
    17. }
    18. }

    session使用的原理

    session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态,服务器创建的每个session对象互不干涉。session是会话级别的变量,我们一般使用 session 处理用户的登陆信息。
    简单的理解,打开一个浏览器,无论你打开多少标签页, 用 session 存储的变量都会存在,除非使用 session.removeAttribute() 将其显式销毁。
    其实可以将session看做在Tomcat中存储的与客户端浏览器窗口绑定的数据存储空间。在使用的时候只需要使用setAttributegetAttribute进行存值和取值即可。但是在底层却不是简单,是如何实现的呢?
    当浏览器第一次创建session对象的时候会tomcat会在内存空间中开辟一个空间存放session数据,并且给session空间一个sessionid,tomcat在返回响应数据的时候会把sessionid一起返回给浏览器,浏览器把sessionid保存在cookie中,之后从浏览器传送过来的数据都通过sessionid来查找session的位置来保存数据。
    4.Servlet与Jsp进阶 - 图14
    session在工程的使用是非常广泛的,最常用的就是根据session可以与浏览器对应的原理,用于保存每个用户的登录信息。

    ServletContext

    ServletContext(Servlet上下文对象),是web应用的上下文对象。在一个Web应用程序中只会存在一个ServletContext对象,该对象在Tomcat启动的时候创建,在Tomcat关闭的时候销毁。
    4.Servlet与Jsp进阶 - 图15
    类似于这种网站备案信息和版权信息,会显示于整个网站全局,这个时候我们就可以使用ServletContext这种全局对象来进行设置。

    1. @WebServlet("/servletcontext/init")
    2. public class ServletContextInitServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public ServletContextInitServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. //获取应用程序上下文对象,其实也就是应用程序对象
    9. ServletContext sc = request.getServletContext();
    10. //利用该对象的特性,设置作用范围为全局的自定义属性
    11. sc.setAttribute("copyright", "Powered by EduSoho v8.6.4 ©2014-2020 课程存档 \n课程内容版权均归 南通在渡教育咨询有限公司 所有 苏ICP备18015371号");
    12. //sc.setAttribute("copyright","");如果设置了相同的属性名,则新的属性值会覆盖旧的属性值,其他设置request自定义属性和session自定义属性也是相同的道理
    13. sc.setAttribute("title", "渡课IT教育");
    14. response.getWriter().println("init success");
    15. }
    16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. }
    18. }
    1. @WebServlet("/servletcontext/defualt")
    2. public class ServletContextDefaultServlet extends HttpServlet {
    3. private static final long serialVersionUID = 1L;
    4. public ServletContextDefaultServlet() {
    5. super();
    6. }
    7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. ServletContext sc = request.getServletContext();
    9. String copyright = (String)sc.getAttribute("copyright");
    10. String title = (String)sc.getAttribute("title");
    11. response.setContentType("text/html;charset=utf-8");
    12. response.getWriter().println("<h1>" + title + "</h1>" + copyright);
    13. }
    14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15. }
    16. }

    Java Web三大作用域

  • HttpServletRequest -请求对象
  • HttpSession - 用户会话对象
  • ServletContext - web应用全局对象

这三个对象的作用域,从上到下是依次递增的。
请求对象,它的生命周期最短,当浏览器发送请求到Tomcat,则请求对象就被创建,当servlet处理完成并返回响应到浏览器时,当前的请求对象就会被销毁。
用户会话对象用于保存与浏览器窗口对应的数据,该对象是在用户第一次向浏览器发送请求的时候被创建,默认情况下,这个对象如果在三十分钟后没有访问就会被销毁。注意一下,关闭浏览器该对象不会被销毁,销毁的是保存在浏览器cookie中的sessionId。就好像银行卡与存在银行中的钱一样,丢失了银行卡,但是银行中的钱还在,只是取不出来这笔钱而已。
全局对象在web应用启动的时候就被创建了,只有在web应用程序关闭或重启的时候才会被销毁。
有个注意点,为了程序维护的需要和资源避免浪费的情况,如果能用小作用域完成的任务就不用大作用域完成,所以request请求对象是以后使用的最多的对象

中文乱码

image.png
中文乱码的核心就是解析字符集不支持中文,所以解决中文乱码的关键就是将默认字符集变成UTF-8,servlet中的请求与响应都需要设置为UTF-8。

Post请求中文乱码

request.setCharacterEncoding方法用于将请求体中的字符集转换为UTF-8,对于get请求,没有请求体,所以该方法只对post请求生效。且必须写在第一行

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Insert title here</title>
  6. </head>
  7. <body>
  8. <form action="/servlet_advanced/charset/process" method="post">
  9. 姓名:<input name="ename">
  10. 地址:<input name="address">
  11. <input type="submit" value="提交">
  12. </form>
  13. </body>
  14. </html>
  1. @WebServlet("/charset/process")
  2. public class CharsetServlet extends HttpServlet {
  3. private static final long serialVersionUID = 1L;
  4. public CharsetServlet() {
  5. super();
  6. }
  7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  8. }
  9. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  10. //request.setCharacterEncoding方法用于将请求体中的字符集转换为UTF-8,对于get请求,没有请求体,所以该方法只对post请求生效。
  11. request.setCharacterEncoding("UTF-8");
  12. String ename = request.getParameter("ename");
  13. String address = request.getParameter("address");
  14. System.out.println(ename + ":" + address);
  15. //通过字符串构造器将字符串的解析字符集转换为utf-8,但是不怎么方便,所以使用setCharacterEncoding方法
  16. //String utf8Ename = new String(ename.getBytes("iso-8859-1") , "utf-8");
  17. //String utf8Address = new String(address.getBytes("iso-8859-1") , "utf-8");
  18. //System.out.println(utf8Ename + ":" + utf8Address);
  19. }
  20. }

Get请求与响应中文乱码

  1. @WebServlet("/charset/process")
  2. public class CharsetServlet extends HttpServlet {
  3. private static final long serialVersionUID = 1L;
  4. public CharsetServlet() {
  5. super();
  6. }
  7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  8. //对于Tomcat8.x的版本,默认get请求发送中文就是UTF-8的格式,因此无需转换
  9. String ename = request.getParameter("ename");
  10. String address = request.getParameter("address");
  11. System.out.println(ename + ":" + address);
  12. //响应乱码不区分get和post请求
  13. response.setContentType("text/html;charset=utf-8");
  14. response.getWriter().println(ename + ":" + address);
  15. }
  16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. }
  18. }

web.xml的常用配置

在本章节中,我们将做到以下功能:

  • 修改web应用默认首页
  • Servlet通配符映射及初始化参数
  • 设置404,500等状态码首页

修改web应用默认首页

  1. <welcome-file-list>
  2. <!-- 指定默认首页,二级目录下的页面也可以作为默认首页,使用的时候需要在地址后面注意加/ -->
  3. <welcome-file>index.html</welcome-file>
  4. <welcome-file>default.html</welcome-file>
  5. </welcome-file-list>

通配符映射,利用地址传参(非get提交)

  1. public class PatternServlet extends HttpServlet{
  2. @Override
  3. protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4. //查询员工的基本信息
  5. //获取当前访问的URL
  6. String url = request.getRequestURL().toString();
  7. System.out.println(url);
  8. String id = url.substring(url.lastIndexOf("/") + 1);
  9. int eid = Integer.parseInt(id);
  10. response.setContentType("text/html;charset=utf-8");
  11. PrintWriter out = response.getWriter();
  12. out.println(id);
  13. if(eid == 1) {
  14. out.println("张三");
  15. }else if(eid == 2) {
  16. out.println("李四");
  17. }else {
  18. out.println("其他员工");
  19. }
  20. }
  21. }
  1. <servlet>
  2. <servlet-name>patternServlet</servlet-name>
  3. <servlet-class>com.dodoke.servlet.pattern.PatternServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>patternServlet</servlet-name>
  7. <!-- 使用*作为通配符,指的是pattern/后面不管是什么地址,都会被该servlet拦截请求 -->
  8. <url-pattern>/pattern/*</url-pattern>
  9. </servlet-mapping>

设置全局参数

在之前的学习中,我们在设置网站备案信息和版权信息时,是将内容写死在程序中的,这其实对我们的程序来说不算友好,现在我们可以尝试着将这些全局信息写入到配置文件中。

  1. <context-param>
  2. <param-name>copyright</param-name>
  3. <param-value>Powered by EduSoho v8.6.4 ©2014-2020 课程存档 \n课程内容版权均归 南通在渡教育咨询有限公司 所有 苏ICP备18015371号</param-value>
  4. </context-param>
  5. <context-param>
  6. <param-name>title</param-name>
  7. <param-value>渡课IT教育</param-value>
  8. </context-param>
  1. @WebServlet("/servletcontext/init")
  2. public class ServletContextInitServlet extends HttpServlet {
  3. private static final long serialVersionUID = 1L;
  4. public ServletContextInitServlet() {
  5. super();
  6. }
  7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  8. ServletContext context = request.getServletContext();
  9. //获取ServletContext对象通过配置文件设置的初始化参数
  10. String copyright = context.getInitParameter("copyright");
  11. context.setAttribute("copyright", copyright);
  12. String title = context.getInitParameter("title");
  13. context.setAttribute("title", title);
  14. response.getWriter().println("init success");
  15. }
  16. }

设置404,500等状态码首页

  1. <!-- 指定错误页面 -->
  2. <error-page>
  3. <error-code>404</error-code>
  4. <location>/error/404.html</location>
  5. </error-page>
  6. <error-page>
  7. <error-code>500</error-code>
  8. <location>/error/500.jsp</location>
  9. </error-page>
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Insert title here</title>
  6. </head>
  7. <body>
  8. 资源不存在
  9. </body>
  10. </html>
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Insert title here</title>
  6. </head>
  7. <body>
  8. 服务器内部错误,请联系管理员
  9. </body>
  10. </html>

JSP九大内置对象

内置对象,又叫做隐含对象,不需要预先声明就可以在脚本代码和表达式中随意使用
1. 由JSP规范提供,不用编写者实例化。
2. 通过Web容器实现和管理
3. 所有JSP页面均可使用
4. 只有在脚本元素的表达式或代码段中才可使用
4.Servlet与Jsp进阶 - 图17

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8" %>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <meta charset="UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. <%
  11. String url = request.getRequestURL().toString(); // HttpServletRequest
  12. response.getWriter().println(url);//HttpServletResponse
  13. %>
  14. <% out.println("<br>ABCCC");
  15. session.setAttribute("user", "张三");
  16. out.println((String)session.getAttribute("user"));
  17. %>
  18. <%
  19. String cp = application.getInitParameter("copyright") ; //ServletContext
  20. out.println("<hr/>");
  21. out.println(cp);
  22. //pageContext可以帮助我们快速获取其他对象
  23. pageContext.getRequest();
  24. pageContext.getResponse();
  25. pageContext.getSession();
  26. pageContext.getServletContext();
  27. %>
  28. </body>
  29. </html>

利用exception对象显示错误信息。

  1. <!-- isErrorPage表示该页面专门用于显示错误 -->
  2. <%@ page contentType="text/html;charset=utf-8" isErrorPage="true"%>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <meta charset="UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. 服务器内部错误,请联系管理员 ,错误信息如下:
  11. <%
  12. String msg = exception.getMessage();
  13. out.print("<br>" + exception.getClass().getSimpleName() + ":" + msg);
  14. %>
  15. </body>
  16. </html>

Java Web的打包与发布

在编写完成代码后,就需要正式的进行程序的上线了,那么我们该如何进行程序的上线呢?
4.Servlet与Jsp进阶 - 图18
4.Servlet与Jsp进阶 - 图19
4.Servlet与Jsp进阶 - 图20
直接将这样的war包,保存到Tomcat的webapp目录中,启动Tomcat就可以了。
注意:

  • 端口可以改为80,避免输入端口号
  • 项目路径可以只保留斜杠,避免输入项目路径
  • 4.Servlet与Jsp进阶 - 图21