(Servlet)servlet核心(GenericServlet,HttpServlet,Request(请求))

GenericServlet:
是一个实现了Servlet接口的抽象类,目的是对于使开发人员不用再敲出不用实现的方法
具体实现步骤如下

这属于缺省适配器设计模式
一个类实现一个接口的大多数方法,但是留一些方法不实现定义为抽象方法,留给子类实现

先定义一个GenericServlet抽象类

public abstract class GenericServlet implements Servlet {

	@Override
	public void init(ServletConfig config) throws ServletException {

	}

	@Override
	public ServletConfig getServletConfig() {
		return null;
	}

	
	//把我们需要自己编写的内容定义为抽象方法,因为抽象方法是要再子类中实现的
	//没有定义为抽象方法的方法,在子类中不用实现,直接就继承了
	//抽象方法,在子类中必须要实现
	@Override
	public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException ;

	

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void destroy() {

	}

}

在他的实现类中获取servletConfig对象

public class TestServlet extends GenericServlet {

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		//获取servletConfig对象,通过getServletConfig对象来获取
		ServletConfig servletConfig = this.getServletConfig();
		System.out.println(servletConfig)
	}
}

以上可以看出每次如果想要调用servletConfig的时候,都需要获取servletConfig对象,所以直接用GenericServlet实现ServletConfig接口,那么就成了servletConfig里的方法成了本地方法,可以直接调用

public abstract class GenericServlet implements Servlet ,ServletConfig{

	private ServletConfig config;

	@Override
	public void init(ServletConfig config) throws ServletException {
		this.config = config;
	}

	@Override
	public ServletConfig getServletConfig() {
		return config;
	}

	
	//把我们需要自己编写的内容定义为抽象方法,因为抽象方法是要再子类中实现的
	//没有定义为抽象方法的方法,在子类中不用实现,直接就继承了
	//抽象方法,在子类中必须要实现
	@Override
	public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException ;

	

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void destroy() {
	}
	//实现ServletConfig里的方法,子类中就可以直接调用ServletConfig内部的方法
	@Override
	public String getInitParameter(String name) {
		return config.getInitParameter(name);
	}
	@Override
	public Enumeration<String> getInitParameterNames() {
		return config.getInitParameterNames();
	}
	@Override
	public ServletContext getServletContext() {
		return config.getServletContext();
	}
	@Override
	public String getServletName() {
		return config.getServletName();
	}
}

GenericServlet的Init()方法

1.主要问题发生有ServletConfig空指针异常,如果在子类中重写该方法,容易忘记

super.init(config)

2.在父类中专门定义一个拿个子类重写的init方法,并且在init方法中就直接调用

同时一下也是一种设计模式,称为模板方法设计模式

public void init(ServletConfig config) throws ServletException {
		this.config = config;
		init();
	}
	/*
	 * 为了防止出现config空指针异常的问题,自己定义一个init方法,在系统定义的init的放啊中访问
	 * */
	
	//专门拿来给子类重写的
	public abstract void init();

总结以上,调用系统定义好的GenericServlet,和我们之前的代码是一样的

httpServlet

观察从表单中所提交的信息

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<!-- 表单 -->
<body>
	<form action="loginServlet"  method = "POST"> <!-- POST提交时,不显示提交的内容 -->
			用户名:<input type = "text" name = "username"/><br>
			<input type = "submit" value = "登陆"/>
	</form>
</body>
</html>

获取请求提交的方式,通过HttpServletRequest (ServletRequest的子类)

//先将其转化为HttpServletRequest
		HttpServletRequest request= (HttpServletRequest)req;
		
//调用方法获取它的提交方式
		System.out.println(	request.getMethod());

定义一个HttpServlet类,然后我们定义的Servlet再直接继承与HttpServlet,目的在于可以对get,或者post请求进行区分
具体需求:如对于GET请求,可能是非法的,我们需要区别与POST请求处理
有 doGet 和 doPost 两个方法,分别处理不同的请求

POST请求更加的安全,

GenericServlet继承于Servlet, GenericServle特点实现了Servlet,ServletConfig
HttpServlet继承于GenericServlet,HttpServlet的特点是对浏览器提交的请求进行了分析有,doGet方法,doPost方法,两个方法,分别对Get和Post两种请求方式进行处理。

可以观察到HttpServlet的源码,service方法会自动执行,并且会在内部调用doGet方法与doPost方法

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200327164549463.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,sh在这里插入图片描述
快速定义Servlet
不再是通过类,而是在web项目中直接找到servlet来创建
默认是继承与HttpServlet

HttpServletRequest

HttpServletRequest会将浏览器发生过来的协议存在内部
浏览器发送的HTTP协议如下

我们知道HttpServletRequest是一个接口,所以他具体实现类应该是一个实现了HttpServletRequest接口的类,但是面向抽象编程,不用关心他的具体实现类
一个请求对应一个HttpServletRequest
请求对象是服务器创建的

POST /09-httpServlet/loginServlet HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 9
Cache-Control: max-age=0
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36
Sec-Fetch-Dest: document
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Referer: http://localhost:8080/09-httpServlet/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: _ga=GA1.1.1634150355.1576843207		

*/
username = 

请求参数:获取浏览器提交表单里的一些数据,比如username
1.获取指定名称的请求参数
方法:String getParameter(String name);
如果提取的表单里有age这个name,可以获取提交的值

String value = req.getParameter("age");
System.out.println(value);

2.获取提交的所有的name,是一个枚举类型

Enumeration<String> pn = req.getParameterNames();
		while(pn.hasMoreElements()) {
			String name = pn.nextElement();
		
			String value  = req.getParameter(name);
			
			System.out.println("name="+name+"value="+value);
		}

3.获取提交的数据,通过Map的形式
getParameterMap(String,String[])
key放的是name
value放的是name对应的值,是一个字符串数组
比如有一种复选框,就是一个name对应多个value值

<input type = "checkbox" name = "hobby" value = "running"/>跑步
<input type = "checkbox" name = "hobby" value = "swimming"/>游泳
<input type = "checkbox" name = "hobby"  value = "reading"/>阅读

复选框的样式为
在这里插入图片描述
如果全部勾选并提交的话,会得到hobby=running&hobby=swimming&hobby=reading
这样一个name会有3个value值

//在servlet中进行读取
	String[] strs = req.getParameterValues("hobby");
		for(String str:strs) {
			System.out.println(str);
	}

以Map的方式获取name和value

 /* 
		 * 获取存放请求的Map 
		 * */
		Map<String, String[]> pm = req.getParameterMap();
		Set<String> keySet = pm.keySet();
		for(String s1:keySet) {
			System.out.println("name = "+s1);
			String[] pv = req.getParameterValues(s1);
			for(String str:pv) {
				System.out.println("value = "+str);
			}
		}

总结:
1.请求参数是存放在Map中的
2.这个Map的key为请求参数的名称,为String类型
这个Map的value为请求参数的所有值,为String[]类型
3.使用最多的是getParameter()方法,其等价于getParameterValues()[0]

Request中的域属性

作用:主要是用于和其他servlet共享request对象的数据,实现了跨servlet通信
1.在request中也存在域属性空间,用于存放有名称的数据。该数据只有在当前Request请求中进行访问
和域属性相关的方法
在ServletRequest中的方法
setAttribute()
removeAttribute()
getAttribute()
getAttributeNames()

将域属性传到另外一个Servlet(/NewServlet)中执行
request.getRequestDispatcher("/NewServlet").forward(request,resp);
在另外一个Servlet中可以通过getAttribute获得域属性

从请求中获取服务器的相关信息的一些需要掌握的方法

getRequestURL():获取请求的URL
getRequestURI():获取请求的URI

getContextPath:获取当前Web应用的根路径

getRemoteAddr():获取客户端IP

getServletPath():返回的是在web.xml中定义的精确匹配路径

getPathInfo():如果有使用同配符号’*’ ,代表的是通配符里填写的路径

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值