常用对象
ServletConfig:用来获取Servlet的初始化参数,web容器向当前servlet传递的信息
初始化值:初始化的值只是让这个servlet有了值,并会显示在哪里,并需调用方法获取
ServletContext
用来获取Servlet的上下文对象,是web容器的一个大管家(可以获取所有servlet,所以servlet也可以操纵它)
获取servletContext: ServletConfig.getServletContext()
1.可以获取全局的初始化参数(不再具体的某个servlet中)
2.ServletContext对象所保存的数据可以被所有的servlet共享
getInitParameter()获取servlet的全局初始化参数
getInitParameterNames()返回全局初始化名字的枚举
getResoutceAsStream(String parh) 获取文件信息返回的是输入流 没什么用
getRealPath(" ") 获取服务器路径
ServletConfig和ServletContext主要区别:
1.一个ServletConfig对应一个servlet,获取单个servlet的初始化参数
2.ServletContext是全局的,一个对应ServletContext对应多个servlet,操作的是初始化数据是定义在每一个servlet之外的
表单数据Request, Response常用方法
HttpServletRequest 封装着一次用户请求(所有的请求参数都封装在内)
HttpServletResponse 用服务器向网页进行相应数据(内有字节流和字符流)
HttpServletRequest常用方法
1.四个获取请求参数的方法
2.域属性的四个方法
3.转发
4.获取请求相关路径
getRequestURL() 获取请求的URL http://localhost:8080/工程名/访问路径
getRequestURI() URL去掉协议和主机 /工程名/访问路径(可能是某个文件夹或直接暴漏)
getContextPath() 获取当前web应用的根路径 /工程名
getRemoteAddr() 获取客户端地址
比如访问路径是 /aaa/bb/dd/*
getServletPath() 获取访问路径的精确部分 /aaa/bb/dd
getPathInfo() 获取请求路径的非精确部分 /*
HttpServletResponse常用方法
以流的形式发送到客户端
getWriter() 用于获取专门向浏览器输出字符数据的标准输出流 PrintWriter
addCookie(Cookie cookie) 增加cookie
获取请求参数的方法
getParameter("name"):您可以调用 request.getParameter() 方法来获取表单参数的值。
name表示的是表单中的name属性的值(返回值是字符串)
getParameterValues():如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框(每个选项的name值要相同)
getParameterNames():如果您想要得到当前请求中的所有参数的完整列表,则调用该方法。
getParameterMap(): 获取请求的map集合
很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序。浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法。(html写到WebContent中)
注意:如何将html的表单数据关联servlet(也就是提交html之后跳转到servlet网页),表单元素中有一个action属性,它表示的是表单在结束也就是提交后执行的动作(调转到哪里),所以把action的值设置为想要跳转的servlet类对应的访问路径,就可以实现跳转了(类与表单的get和post要相对应),html的数据经过提交就把对应的数据通过name=value方式或数据包的方式传给了跳转到的servlet对应的网页地址栏头,servlet通过网页地址栏或数据包进行获取(每个servlet只有一个访问地址(网页),所以每个servlet知道应该获取哪个网页里的信息)
get请求类似于信封,post请求类似于信,信封上数据量少,速度快,并且不适合传递敏感信息,信上内容数据多,但是速度慢,适合传递敏感信息
在实际开发的过程当中大多数使用的都是post请求,默认的请求方式是get
1.doGet()用于处理表单里的get请求(或未指定请求)
Get请求的数据会随着浏览器的地址一起发送到后台服务器,用户可以看到请求的数据
doPost()方法传递数据的形式,Post请求的数据会打成一个数据包随着请求头一起发送到服务器用户不可见�。
域属性
在request存在一块用于存放数据的空间,该数据只在当前request请求中访问,只要请求存在就可以获取请求域中指定属性的值,其主要就是为了实现数据传递的
1.setAttribute(name,value)
name:绑定名称
value:绑定的值
2.removeAttribute(name) 移除绑定的属性
3.getAttribute(name) 获取指定属性
4.若添加多个数据,转发到的jsp/servlet获取方式 获取所有属性
Enumeration
while(names.hasMoreElements){
String name=names.nextElement();
String ele=request.getAttribut(name)
}
请求转发与重定向
可以在servlet和servlet/servlet和jsp/jsp和jsp间发生
解决逻辑和页面显示在jsp,逻辑处理在servlet
请求转发与重定向的理解
类似介绍对象
转发:浏览器想和资源1处对象,资源1觉得不是很好但是没有直接告诉浏览器,而是把它介绍给了住在一起的资源2,资源2最终对浏览器做出了回应。这个过程浏览器只发送了一次请求,请求的地址没有发生变化。
重定向:浏览器想和资源1处对象,资源1觉得不是很好就直接告诉了浏览器,并介绍浏览器去和资源2处对象并把资源2的地址告诉给了浏览器,于是浏览器去资源2住的地方请求资源2处对象,资源2对浏览器做出回应,这个过程浏览器发送了两次请求,并且请求地址也发生了变化
请求转发:资源1得到请求后,将这个请求转发给下一个资源(可以在这个请求中通过域属性添加一些数据)。(1)只请求一次 ,(2)网址并没有发生变化,(3)转发的过程中携带着浏览器的请求(因为这一次请求并没有结束,所以我们可以把请求添加数据后再进行转发)(4)只能跳转当前应用资源
重定向:资源1得到请求后,回应给浏览器另一个资源的地址,让它去请求另一个资源,浏览器请求另一个资源后得到的回应就是最终的回应。(1)请求了两次,(2)网址发生了变化,可以防止表单重复提交(3)请求结束后所存数据也就没有了,因此重定向第一次请求所存数据第二次请求中是不存在的(4)不仅可以跳转当前应用资源,也可以跳转其它应用给的资源
实现转发:
1绑定数据request.setAttribute(name,value) name:绑定名称 value:绑定的值
value是要存到请求中的值,而name相当于map中的key,jsp可通过这个获取值
2.获取转发器/3.实现转发
request.getRequestDispatcher("转发到的路径").forward(request,reponse)
获取绑定数据
request.getAttribute(name)
注意:除了使用forward实现数据转发我们还可以使用include实现请求转发,两者对于请求来说都是一样的,不同点主要实在响应对象中
实现重定向(少用于数据传输)
response.sendRedirect("重定向地址")
注:重定向请求发生改变因此重定向不能在请求中存在数据,我们可以在重定向的地址中做相应的操作实现数据的传递 "other?pname=zz&page=23"但是http传输数据采用的是字节方式,如果想传输汉字到地址栏上,我们需要采用以下方式
name = URLEncoder.encode(name,"UTF-8") //将汉字打散成字节,然后传递
response.sendRedirect("other?pname="+name)
另一个servlet
String pname=request.getParameter("pname")
pname=URLDecoder.decode(pname,"UTF-8") //打散后当然又要组装起来
pname=new String(pname.getBytes("ISO8859-1","UTF-8"))
打散和组装都是更改的http地址的传输方式
注:使用这种方法来获取get请求地址栏的参数是在地址栏上的参数是通过字节方式显示的时候,之后如果显示的是汉字采用正常的转码就可以了
转发与重定向的应用场景
(1)若需要跳转到其它应用使用重定向
(2)防止表单数据的重复提交使用重定向
(3) 转发一般一个组件的业务没有处理完成交给下一个组件去做,而重定向是当前组件已经把业务处理完成之后,跳转到其它组件
注意:转发过程中,请求和转发是通过servlet控制的,而响应是通过服务器寻找到对应资源自动做出的响应;重定向过程中,第一次请求和响应是通过servlet控制的,而第二次的请求和响应是服务器转到对应资源后自动做出的。
关于get与post请求的中文乱码的问题
产生原因:浏览器输入汉字(汉字编码utf-8),浏览器会将其传给服务器,服务器默认采用iso8859-1编码对它们进行解析,解析后在控制台显示。
注:ecplise把编码改成utf-8
1.修改tomcat下的文件编码为utf-8(这样若每个程序的编码不同就不可以了)
2.在程序中将请求得到的数据改为utf-8的数据,手动将回应的编码方式改为utf-8
两种手动方式修改编码
1.将服务器的解析编码的方式更改为utf-8,这样得到的数据就是utf-8了,
req. setcharacterEncoding("UTF-8") 这个必须使用的post提交方式
2.将服务器解码后的数据转码为utf-8(get) 因为get传输是通过网页的编码实现的,不可更改
回应的时候只能选择第一种方式,因为B/S架构在浏览器中无法处理数据
注解
除了用xml进行servlet的匹配,我们还可以使用注解的方式进行servlet的匹配
@WebServlet(" 规则 ")
匹配规则
1.精确匹配与请求路径的名称要一致
2.通配符匹配以/* “*”代表“/”后面跟任意一个值都可以访问 /只会拦截静态请求
注意:这时候工程下若有html文件,通过服务器访问html文件也会显示的是servlet的内容,也就是通配符匹配表示的是,通过本服务器不管运行什么文件,都会访问本servlet内容
由于工程可能有多个模块,也就是多个类的servlet,所以正常情况下是不会这么使用的,我们会使用@WebServlet("/emp/*")表示的是emp/后面跟什么都可以,这样确保了emp下的servlet的访问地址是什么都可以,而不是所有的servlet的访问地址是什么都可以
3.后缀匹配*.(do,action ,a,n)注意“*”这里必须写“*”如果不写“*”会报错,因为servlet容器会把该地址作为精确匹配来走,但是使用精确匹配前面必须得有“/”
后缀匹配其实也就是把工程放到了后缀
三种匹配规则的优先级
精确匹配>通配符匹配>后缀匹配>页面的路径
单一控制器
使用单一控制器处理请求(不适用它之前,增删改查都需要有一个servlet)
使用单一控制器之后,对同一个对象的多个请求可以放在一个servlet里
这时候我们使用后缀匹配
@WebServlet("*.do")
获取*表示的内容,通过其代表的内容决定走的请求
所以我们要先获取*表示内容
String path=request.getRequestURI() //这样我们就获得了请求的路径
也可以使用 pathInfo() 获取请求路径的非精确部分/*
/工程名/请求.后缀
这时我们想要获得这个字符串中请求的内容,我们要用到字符串中的方法
path=path.substring(path.lastIndexOf("/")+1,path.lastIndexOf("."))
这样我们就获得了请求的内容,之后通过equals方法进行比较,执行响应请求就可以了