原文链 id="最全的javaweb知识全集">最全的javaweb知识全集
Servlet是java定义的Servlet标准接口
servlet容器负责Servlet和客户的通信以及调用Servlet的方法
public interface Servlet { void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); void destroy();}servlet生命周期
生命周期相关方法,servlet生命周期中的方法全是由servlet容器来调用的
- 构造器
- init方法
- service方法
- destory方法
init方法
init方法在第一次创建servlet时被调用,在后续每次请求时都不会被调用。
当用户调用servlet的时候,该servlet的一个实例就会被创建,并且为每一个用户产生一个新的线程,init()用于进行一些初始化数据的加载和处理,这些数据会被用于servlet的整个生命周期
void init(ServletConfig var1) throws ServletException;该方法是由servlet容器调用的
重写init方法
GenericServlet实现了Servlet和ServletConfig,是一个抽象类,并对init(ServletConfig var1)方法进行了一层封装,有一个ServletConfig成员变量,在init()方法中进行了初始化,使得可以直接在GenericServlet中直接使用ServletConfig方法
而我们平时写Servlet大多是继承于HttpServlet类的,在对init方法进行重写时,重写不带参的init()方法即可
//GenericServlet类public void init(ServletConfig config) throws ServletException { this.config = config; this.init();}public void init() throws ServletException {}该方法由GenericServlet的调用,如果需要使用到ServletConfig则调用getServletConfig()方法来获取
service方法
service方法是实际处理请求的方法,servlet容器调用service方法来处理请求,并将响应写会到客户端,每次服务器接收到一个新的servlet请求时,服务器会产生一个新的线程来调用服务
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;处理请求逻辑
HttpServlet继承了GenericServlet,重写了service方法,将ServletRequest和ServletResponse转换为HttpServletRequest和HttpServletResponse,并根据不同的请求方式进行分发,doGet/doPost/doHead等
servlet可以在任何协议下访问 ,写的Servlet必须实现Servlet接口,在http协议下可以使用HttpServlet ,用来给Web访问的
在HttpServlet类中对于service()方法进行了处理,根据请求方式的不同,将请求分发到了不同的方法,而我们一般情况下写Servlet也是继承自HttpServlet的,所以在写请求处理逻辑时,只需要重写doGet()和doPost()方法即可
// HttpServlet类protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String msg = lStrings.getString("http.method_get_not_supported"); this.sendMethodNotAllowed(req, resp, msg);}protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String msg = lStrings.getString("http.method_post_not_supported"); this.sendMethodNotAllowed(req, resp, msg);}GET方法
GET方法时浏览器向web服务器传递信息的默认方法,会在地址栏上产生很长的字符串,且GET方法有大小限制,请求字符串中最多只能有1024个字符
POST方法
POST方法不将请求信息放到地址中
destroy方法
destory()方法只在servlet生命周期结束时被调用一次。可以在destory()方法中进行一些资源的清理,如关闭数据库连接、停止后台线程等
ServletContext接口
- 该对象代表当前WEB应用,可以获取到web应用的信息
- 可以使用ServletConfig的getServletContext()获取到ServletContext
- 可以获取web应用的初始化参数,这是全局的方法,在web.
- 获取web应用某个文件的绝对路径(在服务器上的路径,不是部署前的方法) getRealPath
- 获取当前应用的名称 getContextPath
- 获取当前web应用的某一个文件对应的输入流 getResourceAsStream() path是相对于当前web应用的根目录
servlet容器
在上面介绍servlet生命周期时,多次提到了servlet容器,其实在设计Servlet时,J2EE jdk只是提供了一个标准,在javax.servlet包以及子包下,而真正的实现是由servlet容器来进行实现的,如tomcat是在servlet-api.jar中实现的
servlet容器
1、可以创建servlet,并调用servlet的相关生命周期方法
2、JSP、Filter、Listener
下面将以tomcat作为servlet容器为例介绍web应用
web应用
WEB-INF
静态页面不要放在WEB-INF下,WEB-INF是给tomcat用的
WEB-INF 对于web应用的描述
- web.tomcat配置项目位置
tomcat映射配置任意目录的项目
在conf下新建catalina文件夹,新建localhost文件夹,
在其中新建一个path当前没用 docBase为项目路径(编译之后的项目)
<Context path="" docBase="" reloadable="true">请求转发和请求重定向
// 请求转发request.getRequestDispatcher(url).forward(req,resp)// 请求重定向response.sendRedirect(url)
// 请求转发request.getRequestDispatcher(url).forward(req,resp)// 请求重定向response.sendRedirect(url)本质区别:请求转发只向服务器发起一次请求,重定向发起两次请求
1、
请求转发:地址是初次发出请求的地址
重定向:地址栏是最后响应的地址
2、
请求转发:在最终的Servlet中,request对象和中转的那个request是同一个对象
重定向:在最终的Servlet中,request对象和中转的那个request不是同一个对象
3、
请求转发:只能转发到当前web应用
请求重定向:可以重定向到任何资源
4、
请求转发:/代表当前web应用的根目录
请求重定向:/代表当前web站点的根目录,要使用request.getContextPath()再加上路径
会话管理
HTTP是无状态的协议,每次客户端访问web页面时,都会打开一个单独的连接到web服务器,服务器不会自动保存客户端请求的任何记录,需要使用cookie和session来将一系列的请求和响应关联起来,维持客户端和服务器之间的会话
cookie
Cookie是存储在计算机上的文本文件,用于追踪各种信息,记录在客户端,浏览器可以禁用cookie,可以删除cookie,
在服务器产生,作为响应头的一部分返回给客户端,浏览器收到cookie后,把cookie的键值写入到文本中,发送请求时浏览器会把cookie信息与请求发送给服务器
cookie原理
底层原理:WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求信息中增加Cookie请求头字段将Cookie回传给WEB服务器
操作cookie
创建cookie
// 第一个参数是cookie的键,第二个参数是cookie的值Cookie cookie = new Cookie("name","value")resp.addCookie(cookie)获取cookie
Cookie[] cookies = req.getCookies();设置cookie的一些方法
// 描述cookie的注释public void setComment(String purpose) { this.comment = purpose;}// 设置cookie适用的域名public void setDomain(String pattern) { this.domain = pattern.toLowerCase(Locale.ENGLISH);}// 设置过期时间(单位是秒),如果不设置,cookie在当前session中有效// 如果设置生命周期会写在文件里// 如果不设置生命周期会写在浏览器内存里,窗口关闭,cookie就没了public void setMaxAge(int expiry) { this.maxAge = expiry;}// 设置cookie适用的路径,如果不指定,在当前目录及其子目录的URL下会返回cookiepublic void setPath(String uri) { this.path = uri;}// 是否只在加密的连接上(SSL)发送public void setSecure(boolean flag) { this.secure = flag;}// 设置cookie值public void setValue(String newValue) { this.value = newValue;}public void setVersion(int v) { this.version = v;}获取cookie属性的方法
// 获取cookie的注释,如果没有为nullpublic String getComment() { return this.comment;}// 获取cookie适用的域名public String getDomain() { return this.domain;}// 获取cookie过期时间,如果为-1,cookie表示持续到浏览器关闭public int getMaxAge() { return this.maxAge;}// 获取cookie适用的路径public String getPath() { return this.path;}// 获取是否只在加密的连接上发送public boolean getSecure() { return this.secure;}// cookie的名称,创建后不可修改public String getName() { return this.name;}// 获取cookie值public String getValue() { return this.value;}public int getVersion() { return this.version;}删除cookie
设置生命周期 cookie.setMaxAge()方法设置,秒为单位,若为0,表示立即删除该cookie,将该cookie放到响应中返回
注意:一个servlet设置的cookie可以被同一个路径下或者子路径下的servlet读到,其他访问不到
路径是指url可以通过cookie.setPath()方法设置cookie的作用范围
cookie适用场景
- 自动登录,不需要填写用户名和密码
- 浏览记录
session
session是记录在服务器端,获取session需要把sessionId传递给服务端,通过sessionId来取到对应的session,关闭浏览器,session不会被销毁,还可以通过sessionId找到该session,在同一个application下的servlet/jsp可以共享一个session,前提是同一个客户端窗口
操作session
创建或获取session
// 若为false,如果当前没有关联的session,如返回null;若为true,如果没有则会创建 默认是trueHttpSeesion session = request.getSession(true); session的相关方法
// 返回session的创建时间(单位毫秒)long getCreationTime();// 获取sessionIdString getId();// 返回客户端最后一次发送与该session会话相关的请求的时间(单位毫秒)long getLastAccessedTime();ServletContext getServletContext();// session的过期时间,单位秒// 也可以在web.// 判断当前请求的session是否合法req.isRequestedSessionIdValid();// 判断当前请求是不是从URL发出的req.isRequestedSessionIdFromURL();// 判断当前请求是不是从cookie发出的req.isRequestedSessionIdFromCookie();session的实现方式
session有两种实现方式
①通过cookie来实现 第一次请求时,响应在响应头set-Cookie中 有sessionId,把sessionId放到cookie中,如果浏览器支持cookie,会把sessionId放到cookie中
默认是存储在内存中的,没有存储在磁盘上,关闭浏览器就会失效
可以进行持久化,使用cookie.setMaxAge
②通过URL重写来实现
response.encodeURL两个作用
- 转码
- URL后加上sessionID
过滤器Filter
可以对请求和响应进行拦截,在访问后端资源之前,拦截这些来自客户端的请求,在发送回客户端之前,处理这些响应
过滤器的类型
- 身份验证过滤器
- 数据压缩过滤器
- 加密过滤器
- 触发访问事件资源的过滤器
- 图像转换过滤器
- 日志记录和审核过滤器
- MIME-类型链过滤器
- Tokenizing过滤器
- 转换
过滤器的使用
需要实现Filter接口
public interface Filter { // 由servlet容器调用,指示一个过滤器被放入服务 void init(FilterConfig var1) throws ServletException; // 在每次一个请求或响应在所对应的资源下时通过链传递,由容器调用 void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; // 由servlet容器调用,指示一个过滤器从服务去除 void destroy();} 在web.
<filter> <filter-name>security</filter-name> <filter-class>com.zhanghe.study.webstudy.filter.SecurityFilter</filter-class> <!--用户名--> <init-param> <param-name>userName</param-name> <param-value>john</param-value> </init-param></filter><!-- 拦截的顺序与在web.异常处理
当servlet出现异常时,servlet容器使用exception-type元素来找到与抛出的异常类型相匹配的配置
public class ExceptionHandler extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Throwable throwable = (Throwable) req.getAttribute("javax.servlet.error.exception"); Integer code = (Integer) req.getAttribute("javax.servlet.error.status_code"); String message = (String) req.getAttribute("javax.servlet.error.message"); System.out.println("========="); System.out.println(throwable); System.out.println("========="); System.out.println(code); System.out.println("========="); System.out.println(message); }}<!-- 配置异常处理的servlet --><servlet> <servlet-name>ExceptionHandler</servlet-name> <servlet-class>com.zhanghe.study.servlet.ExceptionHandler</servlet-class></servlet><servlet-mapping> <servlet-name>ExceptionHandler</servlet-name> <url-pattern>/ExceptionHandler</url-pattern></servlet-mapping><!-- 配置哪些错误码会调用该异常处理类 --><error-page> <error-code>404</error-code> <location>/ExceptionHandler</location></error-page><!-- 配置哪些异常类型会调用该异常处理类 --><error-page> <exception-type>java.lang.ArithmeticException</exception-type> <location>/ExceptionHandler</location></error-page>如果出现异常,会在请求域中设置相应的属性
可以使用request.getAttribute("")取出
javax.servlet.error.status_code //错误码,Integer类型javax.servlet.error.exception_type // 异常类型,Class类型javax.servlet.error.message //异常信息,String类型javax.servlet.error.request_uri //出现异常的uri地址,String类型javax.servlet.error.exception //异常,Throwable类型javax.servlet.error.servlet_name //servlet名称,String类型上传文件
<!-- 上传文件一定要使用post请求 enctype需要设置为multipart/form-data input标签的type类型设为file--><form method="post" enctype="multipart/form-data"><input type="file" name="file">form表单的编码格式
①application/x-www-form-urlencoded 默认 在发送前编码所有字符
②multipart/form-data 不对字符编码,二进制
③text/plain 空格转换为+号,但不对特殊字符编码
使用读取流的方式来读取太过于麻烦 request.getInputStream() 获取到的是整个请求体,需要解析各个字段和分隔
解析multipart/form-data比较复杂
可以使用外部依赖包
commons-fileupload.jar 依赖于 commons-io.jar
<!-- 文件上传 --><dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version></dependency>commons-fileupload解析请求,解析成FileItem集合,无论是文本域还是文件域
使用FileItem.isFormField()来判断是不是一个表单域
表单域 item.getFieldName item.getString
非表单域 item.getFieldName item.getName item.getContentType item.isImemory item.getSize item.getInputStream
转发和重定向
国际化
- 国际化(i18n): i18n internationalization,网站能够提供翻译成访问者的语言或国籍的不同版本的内容
- 本地化(i10n): 向网站添加资源,使其适应特定的地理或文化区域,例如将网站翻译为中文
- 区域设置:通常为语言符号后跟一个由下划线分隔的国家符号。例如"en_US"
获取区域
//获取当前国家和语言Locale locale = request.getLocale();获取区域设置
// 获取该区域设置的国家public String getCountry() { return baseLocale.getRegion();}// 获取该区域设置的国家名称public final String getDisplayCountry() { return getDisplayCountry(getDefault(Category.DISPLAY));}// 获取该区域设置的语言代码public String getLanguage() { return baseLocale.getLanguage();}// 获取该区域设置的语言名称public final String getDisplayLanguage() { return getDisplayLanguage(getDefault(Category.DISPLAY));}// 返回该区域设置的国家的三个字母缩写public String getISO3Country() throws MissingResourceException { String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable); if (country3 == null) { throw new MissingResourceException("Couldn't find 3-letter country code for " + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry"); } return country3;}// 返回该区域设置的语言的三个字母缩写public String getISO3Language() throws MissingResourceException { String lang = baseLocale.getLanguage(); if (lang.length() == 3) { return lang; } String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable); if (language3 == null) { throw new MissingResourceException("Couldn't find 3-letter language code for " + lang, "FormatData_" + toString(), "ShortLanguage"); } return language3;}时间国际化
时间格式化 DateFormat
货币国际化
数字、货币格式化 NumberFormat
字符串国际化
字符串格式化 MessageFormat
String str = "Date: {0},Salary: {1}";Locale locale = Locale.CHINA;Date date = new Date();double sa1 = 12345.12;MessageFormat.format(str,date,sa1);国际化配置
native2ascii命令在jdk下 可以查看ascii码
Locale locale = Locale.CHINA;ResourceBundle bundle = ResourceBundle.getBundle("i18n",locale);在配置文件中i18n.properties i18n_en_US.properties i18n_zh_CN.properties
根据locale来找不同的配置文件
中文乱码问题
GET请求 ①tomcat的server.②tomcat的server.③tomcat的get请求默认使用ISO-8859-1来编码,可以在获取的时候进行转码,new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8")
多个请求使用同一个Servlet
第一种方案:在url加上入参method
根据method进行分发
第二种方案:
web. 根据 request.getServletPath()然后反射调用方法
表单的重复提交
重复提交的情况
①在表单提交到一个Servlet,Servlet又通过请求转发的方式响应了一个页面,此时地址栏还保留着Servlet的那个路径,在响应页面点击刷新
②在响应页面没有到达时重复点击提交按钮
③点击返回,再点击提交
不是重复提交的情况
①点击返回之后,刷新页面,再点击提交
如何避免表单的重复提交
使用session,生成属性,移除属性
HttpServletRequestWrapper类包装原始的request对象,实现了HttpServletRequest接口的所有方法,内部调用了所包装的
request对象的对应方法
相应的也有HttpServletResponseWrapper类来包装原始的response对象
继承HttpServletRequestWrapper,重写
Servlet监听器
用于监听ServletContext、HttpSession、ServletRequest等对象的创建和销毁,以及属性修改
①监听ServletContext、HttpSession、ServletRequest等对象的创建和销毁
ServletContextListener 创建contextInitialized 销毁contextDestroyed
HttpSessionListener 创建sessionCreated 销毁sessionDestroyed
ServletRequestListener 创建requestInitialized 销毁requestDestroyed
实现相应的接口,监听不同的域对象web.②监听域对象 ServletContext、HttpSession、ServletRequest 属性变更的监听器
ServletContextAttributeListener attributeAdded attributeRemoved attributeReplaced
HttpSessionAttributeListener attributeAdded attributeRemoved attributeReplaced
ServletRequestAttributeListener attributeAdded attributeRemoved attributeReplaced
ServletRequestAttributeEvent 可以getName、getValue或者值
③感知session绑定的监听器
保存到Session域中的对象可以有多种状态:绑定到Session中,从Session中解除绑定;随Session对象持久到到一个存储设备中;随Session对象从一个存储设备中恢复
HttpSessionBindingListener和HttpSessionActivationListener接口,实现这两个接口不需要在web.
放到session中的对象实现HttpSessionBindingListener 会触发两个方法 绑定valueBound 解除valueUnBanding实现了HttpSessionActivationListener接口的对象可以感知自己被钝化和被活化的事件 sessionWillPassivate 从内存写到磁盘 sessionDisActivate 从磁盘中读取出来 session会被存储在tomcat当前项目下 .cer文件由于本身的博客百度没有收录,博客地 />
原文转载:http://www.shaoqun.com/a/563577.html
square:https://www.ikjzd.com/w/2106
东杰智能:https://www.ikjzd.com/w/1967
原文链id="最全的javaweb知识全集">最全的javaweb知识全集Servlet是java定义的Servlet标准接口servlet容器负责Servlet和客户的通信以及调用Servlet的方法publicinterfaceServlet{voidinit(ServletConfigvar1)throwsServletException;ServletConfig
rfq:rfq
epa认证:epa认证
亚马逊欧洲站注册流程及审核事项:亚马逊欧洲站注册流程及审核事项
口述:变态老公和女民工帐篷内偷欢老公帐篷民工:口述:变态老公和女民工帐篷内偷欢老公帐篷民工
2021年,外贸行业以及外贸人的出路在哪?:2021年,外贸行业以及外贸人的出路在哪?
没有评论:
发表评论