Servlet与JSP入门(2)

本文介绍了Servlet与JSP的基础知识,包括HTTP请求和响应的结构,ContentType的作用,请求转发与重定向的区别及原理,Cookie与Session的使用,ServletContext的解释,以及Java Web的三大作用域。此外,还探讨了中文乱码处理和web.xml的常见配置,最后提到了JSP的九大内置对象。
摘要由CSDN通过智能技术生成

HTTP请求的结构

     请求是浏览器像服务器发送的数据包,在请求中其实是包含了三部分的内容的:请求行,请求头,请求体。
在这里插入图片描述

  • 请求行包括请求的方式,请求的地址,以及请求的HTTP版本;
  • 请求头中,包括很多辅助的请求信息,能为请求处理提供额外的支持;
  • 请求体中,描述了请求的参数内容。注意一下,get请求是将参数写入URL中,所以get请求是没有请求体的,只有post请求才有请求体。

HTTP响应的结构

HTTP响应包含三部分:响应行、响应头、响应体。
在这里插入图片描述
HTTP常用状态码:
在这里插入图片描述

ContentType的作用

ContentType决定浏览器采用何种的方式对响应体进行处理。
在这里插入图片描述

请求转发与重定向

对于多个servlet和jsp之间跳转有两钟方式:

  1. 请求转发:
request.getRequestDispatcher(path).forword(request,response)
  1. 响应重定向
response.sendRedirect(Contextpath工程名称/映射地址);

两者的区别:

  • 请求转发是不会改变一开始访问的映射地址
  • 响应重定向是会改变到最后请求的映射地址
请求转发与重定向的使用
@WebServlet("/direct/index")
public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("This is index page");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}
/**
 * 用户校验页面
 * @author LiXinRong
 *
 */
@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CheckLoginServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("用户登录成功");
		//请求.请求触发器.转发->浏览器地址栏不会发生改变
		request.getRequestDispatcher("/direct/index").forward(request, response);
        //响应重定向需要增加contextPath->浏览器地址栏会发生改变
		response.sendRedirect("/sd/direct/index");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

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

请求转发与重定向的原理

请求转发
     请求转发是在服务器内部进行跳转,转发调用的是HttpServletRequest对象中的方法以及转发时浏览器只请求一次服务器,地址栏的url不会发生变化。

在这里插入图片描述
在进行请求转发时,允许创建自定义属性。
设置请求属性:

request.setAttribute(属性名,属性值)

获取请求属性:

Object attr = request.getAttribute(属性名)

重定向
重定向则是浏览器端跳转,会产生两次请求。
在这里插入图片描述
重定向的时候不会去传递属性。

注意:

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

Cookie与Session

Cookie
     Cookie(小甜饼)是浏览器保存在本地的文本内容,cookie常用于保存登录状态,用户资料等小文本。cookie是具有时效性的,有效的cookie内容会伴随着请求发送给Tomcat。比如我们可以使用cookie保存用户的登录信息,这样在一定时长内,用户就可以一直保持登录状态了。

设置Cookie

@WebServlet("/cookies/lg")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public LoginServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("用户登录成功");
		//设置用户七天内保持登录
		Cookie cookie = new Cookie("user","admin");
        cookie.setMaxAge(60*60*24*7);
		response.addCookie(cookie);
		response.getWriter().println("login success");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
}

若不设置有效期,则cookie有效期为当前浏览器窗口,若窗口关闭,则cookie清空。

读取cookie

@WebServlet("/cookies/is")
public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public IndexServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Cookie[] cs = request.getCookies();//用于获取所用的用户信息
		String user = null;
		for(Cookie c :cs) {
			System.out.println(c.getName() + ":" + c.getValue());
			if(c.getName().equals("user")) {
				user = c.getValue();
				break;
			}
		}
		if(user == null) {
			response.getWriter().println("user not login");
		} else {
			response.getWriter().println("user:" + user);
		}
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

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

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

session特点:

  • Sesstion(用户会话)用于保存"浏览器窗口"对应的数据
  • Session的数据存储在Tomcat服务器的内存中,具有时效性(无人访问时长为30分钟)
  • Session通过浏览器Cookie的SessionId(浏览器的session识别码)值提取用户数据,每个浏览器的SessionId都不一样。
@WebServlet("/session/sl")
public class SessionLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public SessionLoginServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("用户登录成功");
		//获取用户会话session
		HttpSession session = request.getSession();
		session.setAttribute("name", "张三");
		String sessionId = session.getId();
		System.out.println(sessionId);
		request.getRequestDispatcher("/session/id").forward(request,response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
@WebServlet("/session/sil")
public class SessionIndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public SessionIndexServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		String sessionId = session.getId();
		System.out.println(sessionId);
		String name = (String)session.getAttribute("name");
		response.setContentType("text/html;charset=utf-8");//设置返回内容解码方式
		response.getWriter().println("这是首页,当前用户为:" + name);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

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

在这里插入图片描述


ServletContext

     ServletContext(Servlet上下文对象),是web应用的上下文对象。在一个Web应用程序中只会存在一个ServletContext对象,该对象在Tomcat启动的时候创建,在Tomcat关闭的时候销毁。

@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ServletContextInitServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获取应用程序上下文对象,其实也就是应用程序对象
		ServletContext sc = request.getServletContext();
		//利用该对象的特性,设置作用范围为全局的自定义属性
		sc.setAttribute("copyright", "Powered by EduSoho v8.6.4 ©2014-2020 课程存档 \n课程内容版权均归 南通在渡教育咨询有限公司 所有 苏ICP备18015371号");
		//sc.setAttribute("copyright","");如果设置了相同的属性名,则新的属性值会覆盖旧的属性值,其他设置request自定义属性和session自定义属性也是相同的道理
		sc.setAttribute("title", "渡课IT教育");
		response.getWriter().println("init success");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}
@WebServlet("/servletcontext/defualt")
public class ServletContextDefaultServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ServletContextDefaultServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext sc = request.getServletContext();
		String copyright = (String)sc.getAttribute("copyright");
		String title = (String)sc.getAttribute("title");
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().println("<h1>" + title + "</h1>" + copyright);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}

Java Web三大作用域

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

     这三个对象的作用域,从上到下是依次递增的。
     请求对象,它的生命周期最短,当浏览器发送请求到Tomcat,则请求对象就被创建,当servlet处理完成并返回响应到浏览器时,当前的请求对象就会被销毁。
     用户会话对象用于保存与浏览器窗口对应的数据,该对象是在用户第一次向浏览器发送请求的时候被创建,默认情况下,这个对象如果在三十分钟后没有访问就会被销毁。注意一下,关闭浏览器该对象不会被销毁,销毁的是保存在浏览器cookie中的sessionId。
     全局对象在web应用启动的时候就被创建了,只有在web应用程序关闭或重启的时候才会被销毁。


中文乱码的处理

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

Post请求中文乱码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/servlet_advanced/charset/process" method="post">
		姓名:<input name="ename">
		地址:<input name="address">
		<input type="submit" value="提交">
	</form>
</body>
</html>
@WebServlet("/charset/process")
public class CharsetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CharsetServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//request.setCharacterEncoding方法用于将请求体中的字符集转换为UTF-8,对于get请求,没有请求体,所以该方法只对post请求生效。
		request.setCharacterEncoding("UTF-8");
		String ename = request.getParameter("ename");
		String address = request.getParameter("address");
		System.out.println(ename + ":" + address);
		//通过字符串构造器将字符串的解析字符集转换为utf-8,但是不怎么方便,所以使用setCharacterEncoding方法
		//String utf8Ename = new String(ename.getBytes("iso-8859-1") , "utf-8");
		//String utf8Address = new String(address.getBytes("iso-8859-1") , "utf-8");
		//System.out.println(utf8Ename + ":" + utf8Address);
	}

}

Get请求与响应中文乱码

@WebServlet("/charset/process")
public class CharsetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CharsetServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//对于Tomcat8.x的版本,默认get请求发送中文就是UTF-8的格式,因此无需转换
		String ename = request.getParameter("ename");
		String address = request.getParameter("address");
		System.out.println(ename + ":" + address);
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().println(ename + ":" + address);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

web.xml的常用配置

修改web应用默认首页

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

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

public class PatternServlet extends HttpServlet{

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

设置全局参数

<context-param>
  	<param-name>copyright</param-name>
  	<param-value>Powered by EduSoho v8.6.4 ©2014-2020 内容版权均归 xxxx 所有 苏ICP备2333号</param-value>
  </context-param>
  <context-param>
  	<param-name>title</param-name>
  	<param-value>全局参数</param-value>
  </context-param>
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public ServletContextInitServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext context = request.getServletContext();
		//获取ServletContext对象通过配置文件设置的初始化参数
		String copyright = context.getInitParameter("copyright");
		context.setAttribute("copyright", copyright);
		String title = context.getInitParameter("title");
		context.setAttribute("title", title);
		response.getWriter().println("init success");
	}

}

设置404,500等状态码首页

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

JSP九大内置对象

内置对象,又叫做隐含对象,不需要预先声明就可以在脚本代码和表达式中随意使用。

  1. 由JSP规范提供,不用编写者实例化;
  2. 通过Web容器实现和管理 ;
  3. 所有JSP页面均可使用 ;
  4. 只有在脚本元素的表达式或代码段中才可使用。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值