JavaWeb基础(三)——Servlet内置对象和注解

一,内置对象

1.1 Request对象

1.1.1 获取请求头

getRemoteAddress:获取请求地址

getMethod:获取请求方式

1.1.2 获取请求行

String getHander(String name):获取请求头的内容

String[] getHanderNames():获取所有请求头的名字,返回一个字符串数组

1.1.3 获取请求参数

String getParamter(String name):获取指定的请求参数

String[] getParamterValues(String name):获取相同name属性的多个请求参数

1.1.4 实现请求转发

请求转发就是可以实现Servlet之间的数据通信。

实现请求转发的步骤:

第一步:创建请求分发器对象;

RequestDispatcher rd = request.getRequestDispatcher("请求路径")

注意:请求路径以“/”开头,不需要写上下文名称。

第二步:调用请求分发器对象的forward方法;

rd.forward(request, response)

例如:在ServletA中请求转发给ServletB处理。

@WebServlet("/a.do")
public class ServletA extends HttpServlet {
	
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("执行ServetA...");
		// 第一步:创建一个请求分发器对象
		RequestDispatcher rd = request.getRequestDispatcher("/b.do");
		// 第二步:调用请求分发器对象的forward方法执行请求转发
		rd.forward(request, response);
	}
}

@WebServlet("/b.do")
public class ServletB extends HttpServlet {
	
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("执行ServletB...");
	}

}

注意:请求转发不能够与response.getWriter().write()方法一起使用。

请求转发和请求重定向的区别?

  • 请求转发地址栏不会发生变化,请求重定向的地址栏会发生变化。
  • 如果是请求转发,浏览器只会发起一次请求,而请求重定向浏览器会发起两次请求。
  • 请求转发的地址不需要指定上下文路径,而请求重定向的地址需要指定上下文路径。
  • 请求转发可以通过Request对象实现数据的传递,而请求重定向不可以通过Request对象实现数据传递。、

一般情况,如果需要把数据从一个Servlet传递到另外一个Servlet中,建议使用请求转发。

1.1.5实现不同Servlet之间的数据传递

Request提供了用于实现Servlet之间数据传递的方法:

void setAttribute(String name,Object value):把数据存放在Request对象的name属性中;

Object getAttribute(String name):从Request对象中获取指定name属性的值;

@WebServlet("/a.do")
public class ServletA extends HttpServlet {
	
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		
		// 往request对象中存储数据
		request.setAttribute("name", "aa");
		
		List<String> books = new ArrayList<String>();
		books.add("java基础");
		books.add("java框架");
		books.add("分布式");
		request.setAttribute("books", books);
		
		// 第一步:创建一个请求分发器对象
		RequestDispatcher rd = request.getRequestDispatcher("/b.do");
		// 第二步:调用请求分发器对象的forward方法执行请求转发
		rd.forward(request, response);
	
	}
}

@WebServlet("/b.do")
public class ServletB extends HttpServlet {
	
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 从request对象中获取数据
		String name = (String) request.getAttribute("name");
		System.out.println("name = " + name);
		
		List<String> books = (List<String>) request.getAttribute("books");
		for (String book : books) {
			System.out.println(book);
		}
	}

}

面试题:Servlet有哪些域对象?

域对象:实现不同Servlet之间数据传递的对象。

Servlet的四大域对象:

  • PageContext:在一个JSP页面中有效。
  • Request:在一次请求中有效。(实现Servlet之间数据传递)
  • Session:在一次会话中有效,与浏览器相关的。(存储用户相关的数据)
  • ServletContext:在整个Web应用范围内有效。(存储项目相关的数据,比如项目所使用的字符集)

域对象都有的方法:

void setAttribute(String name, Object value):把数据存放在域对象的name属性中;

Object getAttribute(String name):从域对象中获取指定name属性的值;

void removeAttribute(String name):从域对象中删除指定属性;

1.2 Session对象

1.2.1 基本操作

void setAttribute(String name, Object value):往Session中添加数据。

Object getAttribute(String name):从Session中获取当前用户的数据。

void removeAttribute(String name):从Session中删除当前用户的指定数据。

void invalidate():使当前用户的Session失效。

1.2.2 使用

在实际开发中,使用Session对象存储用户相关的数据。

第一步:获取Session对象

HttpSession session = request.getSession();

第二步:往Session存放数据。

// 往Session中存储数据
session.setAttribute("name", "aa");

第三步:从Session中获取数据。

// 从session中获取数据
Object o = session.getAttribute("name");
System.out.println(o);

因为Session对象的作用范围与浏览器相关。所以理论上,只要浏览器关闭,Session中的数据就会被清空。

1.2.3 细节问题

  • 服务器创建Session对象的时候,它会把session对象的id发送给浏览器,并保存在一个Cookie文件中。当浏览器再次发送请求服务器的时候,服务器就可以根据该id找到服务器中的session对象。但是,如果浏览器禁用了cookie,那么服务器就无法把session对象的id发送给浏览器。这时候程序需要把session的id保存起来,下次请求服务器的时候需要在URL后面加上jsessionid参数。例如:
// 获取sesion对象的ID
String jsessionId = session.getId();
// 对包含jsessionid的url进行加密处理
String url = response.encodeURL("/day08-servlet/sessionB?JSESSIONID=" + jsessionId);
// 重定向时候使用加密后的url
response.sendRedirect(url);
  • session对象与浏览器相关。当浏览器关闭时候,服务器中的session对象并没有消失。但是由于浏览器中保存jsessionid的cookie没有设置有效时间,所以浏览器关闭的时候,浏览器的cookie被清空掉,导致服务器无法通过jsessionid找到对应的session对象。所以,如果想让浏览器关闭后,还能够访问到服务器的session对象,那么可以修改jsessionid的有效时间。如下:
// 修改jessionid的有效时间,保证jesessionid不会随着浏览器关闭而消失
Cookie c = new Cookie("JSESSIONID", session.getId());
c.setMaxAge(60 * 60 * 24);
response.addCookie(c);

除此以外,每一个session对象都有一个有效时间,如果超过了有效时间,那么服务器的对象也会被清空。可以通过在web.xml文件中修改session的有效时间。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d8nNgdW0-1569802858538)(C:\Users\lmc\Desktop\我的笔记\images\assets\20190721005114443.png)]

  • 当服务器重启时候,服务器会把session中的数据保存在磁盘上,这个过程称为session的钝化。当服务器重新启动时候,服务器会从磁盘上把session数据重新加载回来,这个过程称为session的活化。但是,只要这些数据实现了序列化接口,才能够被执行钝化和活化操作。

1.3 ServletConfig对象

作用:获取Servlet中的配置参数。

如果要使用ServletConfig对象,需要重写Servlet的init(ServletConfig config)方法。例如:

public class Demo03Servlet extends HttpServlet {
	String uploadPath;
	String imageType;  
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("执行Demo03Servlet init方法...");
        // 根据参数名获取配置参数的值
		uploadPath = config.getInitParameter("uploadPath");
		imageType = config.getInitParameter("imageType");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("uploadPath = " + uploadPath);
		System.out.println("imageType = " + imageType);
	}

}

在web.xml文件中配置参数:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  
  <servlet>
  	<servlet-name>Demo03Servlet</servlet-name>
  	<servlet-class>demo03ServletConfig对象.Demo03Servlet</servlet-class>
  	<!-- servlet配置参数,一个init-param配置一个参数 -->
  	<init-param>
  		<!-- 参数名 -->
  		<param-name>uploadPath</param-name>
  		<!-- 参数值 -->
  		<param-value>d:/upload</param-value>
  	</init-param>
  	<init-param>
  		<!-- 参数名 -->
  		<param-name>imageType</param-name>
  		<!-- 参数值 -->
  		<param-value>jpg,png,jpeg</param-value>
  	</init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>Demo03Servlet</servlet-name>
  	<url-pattern>/demo03</url-pattern>
  </servlet-mapping>
  
</web-app>

在实际开发中,如果一些数据可能会发生变化,那么这些数据建议在配置文件中进行定义,尽量不要写死在代码中。比如:项目所使用的字符集,文件上传路径,上传文件类型等等。

1.4 ServletContext对象

ServletContext代表一个web应用环境对象,即一个web环境。也就是说ServletContext对象内部封装了该web应用的信息。因此一个web应用只有一个ServletContext对象。

创建时间:web应用被加载(即服务器启动或发布web应用)时;

销毁时间:web应用被卸载(即服务器关闭或者该应用被移除)时;

1.4.1 获取上下文路径

通过Request对象的getContextPath()方法来获取项目的上下文路径。

String contextPath = request.getContextPath();
System.out.println("contextPath = " + contextPath);

1.4.2 获取项目中资源文件

String getRealPath(String path):获取资源文件所在文件夹在磁盘上的绝对路径;

InputStream getResourceAsStream(String filePath):把资源文件读取到输入流中;

@WebServlet("/demo04")
public class Demo04Servlet extends HttpServlet {
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 设置响应头
		resp.setHeader("Content-Disposition", "attachment;filename=good.jpg");
		// 获取images文件夹在磁盘上路径
		ServletContext servletContext = req.getServletContext();
		/*String imagesPath = servletContext.getRealPath("/images");
		System.out.println("imagesPath = " + imagesPath);
		// 读取图片到输入流中
		FileInputStream fis = new FileInputStream(imagesPath + "/good.jpg");*/
		
		// 把资源文件读取到输入流中
		InputStream inputStream = servletContext.getResourceAsStream("/images/good.jpg");
		
		// 创建字节数组
		byte[] buf = new byte[1024];
//		int len = fis.read(buf);
		int len = inputStream.read(buf);
		while (len != -1) {
			// 把读取到的数据输出到浏览器
			resp.getOutputStream().write(buf, 0, len);
//			len = fis.read(buf);
			len = inputStream.read(buf, 0, len);
		}
		// 关闭输入流
		//fis.close();
		inputStream.close();
	}

}

注意:文件路径必须要以“/"开头,“/”代表项目的根路径。

1.5 Cookie对象

会话:从用户打开浏览器并访问服务器开始,直到浏览器关闭为止,这个过程称为一次会话。

简单来说,Cookie其实就是保存在浏览器中的一个小文件而已。每次浏览器请求服务器是的时候,浏览器会带着这个小文件的数据一起发送给服务器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L9aPsrKN-1569802858539)(C:\Users\lmc\Desktop\我的笔记\images\assets\1563953562412.png)]

1.5.1 添加数据

第一步:创建一个Cookie对象;

Cookie c = new Cookie("name",value);

第二步:设置Cookie有效时间;

每一个Cookie都有一个默认的有效时间,以秒为单位。如果没有指定有效时间,默认就是浏览器关闭,Cookie的数据就会消失。

c.setMaxAge(int second);

第三步:设置Cookie有效路径【可选】;

c.setPath("路径");

如果没有设置有效路径,默认为当前项目的上下文路径。

第四步:把Cookie输入到客户端;

response.addCookie(cookie);

【代码】

@WebServlet("/setCookie")
public class SetCookieServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 创建Cookie对象
		Cookie c = new Cookie("name", "jacky");
		// 设置cookie的有效时间
		c.setMaxAge(120);
		// 设置有效路径
		// c.setPath("/day08-servlet/getCookie");
		// 把cookie输出到客户端
		resp.addCookie(c);
	}
	
}

1.5.2 获取数据

第一步:调用request对象的getCookies方法,该方法用于获取客户端请求中包含的所有Cookie。

Cookie[] cookie = request.getCookies();

第二步:遍历Cookie数组;

for(Cookie c : cookies){
    ...
}

第三步:调用Cookie的方法获取Cookie数据;

getName():获取Cookie的名字
getValue():获取cookie的值

【代码】

@WebServlet("/getCookie")
public class GetCookieServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 获取客户端请求中包含的所有Cookie
		Cookie[] cookies = req.getCookies();
		// 遍历Cookie数组
		for (Cookie cookie : cookies) {
			String cookieName = cookie.getName();
			if ("name".equals(cookieName)) {
				String cookieValue = cookie.getValue();
				System.out.println(cookieName + ":" + cookieValue);
				break;
			}
		}
	}
	
}

1.5.3 修改数据

创建一个同名的Cookie,它会覆盖原来的Cookie。

@WebServlet("/updateCookie")
public class UpdateCookieServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 创建Cookie对象
		Cookie c = new Cookie("name", "mickey");
		// 设置cookie的有效时间
		c.setMaxAge(120);
		// 设置有效路径
		c.setPath("/day08-servlet/getCookie");
		// 把cookie输出到客户端
		resp.addCookie(c);
	}
	
}

1.5.4 删除数据

创建一个同名的Cookie,设置有效时间为0.

@WebServlet("/deleteCookie")
public class DelCookieServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 创建Cookie对象
		Cookie c = new Cookie("name", "");
		// 设置cookie的有效时间
		c.setMaxAge(0);
		// 设置有效路径
		c.setPath("/day08-servlet/getCookie");
		// 把cookie输出到客户端
		resp.addCookie(c);
	}
	
}

二,Servlet注解

@注解名(属性...)

使用注解配置的好处:

  • 可读性更强;
  • 相对配置文件更加简单

Servlet3.0以后开始支持使用注解配置方式。

2.1 @WebServlet注解

作用:@WebServlet配置Servlet

@WebServlet注解的属性:

  • value:配置url-pattern。如果只有一个value属性,可以不写value属性名。
  • urlPattern:同上,不能够与value共存。
  • loadOnStartup:指定Servlet的加载顺序,值越小,越先加载。但是该属性必须要指定urlPattern或value属性一起使用;
  • initParams:指定servlet配置参数。它是一个数组,数组元素是@WebInitParam类型。

@WebInitParam:指定一个配置参数,它有两个属性:

  • name:参数名
  • value:参数值
@WebServlet(value={"/load1", "/load2"}, loadOnStartup=1, initParams={
		@WebInitParam(name = "name", value = "jacky"), 
		@WebInitParam(name = "age", value = "20")
})
public class LoadOnStartUpServlet extends HttpServlet {

}

2.2 @WebFilter注解

作用:@WebFilter配置过滤器。

@WebFilter注解的属性:

  • value:配置url-pattern。如果只有一个value属性,可以不写value属性值。
  • urlPatterns:同上,不能与value共存。
  • servletNames:指定要拦截的Servlet的name属性。
  • initParams:指定servlet的配置参数。它是一个数组,数组元素是@WebInitParam类型。

@WebInitParam: 指定一个配置参数,它有两个属性:

  • name:参数名
  • value:参数值
/*@WebFilter(value="/index.html", initParams={
		@WebInitParam(name="charset", value="utf-8")
})*/
@WebFilter(servletNames={"IndexServlet"}, initParams={
		@WebInitParam(name="charset", value="utf-8")
})
public class LoginFilter implements Filter {

}

2.3 @WebListener注解

@WebListener配置监听器

@WebListener
public class MyServletContextListener implements ServletContextListener {
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值