系统架构分类

-C/S    -B/S-C/S:Client/Server优点:速度快,大部分数据已集成到客户端软件中,只需要从服务器上传送少量数据即可。速度很快,用户体验好。大部分的数据集成到了客户端,相对安全。C/S的客户端界面可以非常炫缺点:升级需要每个客户端都升级,升级麻烦需要安装特定的客户端软件,才能访问服务器-B/S:Browser/Server优点:不需要安装特定的客户端软件,只要有浏览器就行,客户在这一方面体验不错,升级只需升级服务器端,方便。缺点:所有数据全部集成在服务器端,一旦发生不可抗力,数据丢失,相对来说不安全速度慢,用户体验差娱乐系统适合使用C/S架构,企业内部的系统适合使用B/S架构。

Tomcat

Tomcat配置:配置bin目录和CATALINA_HOME变量,目的是在命令窗口直接执行服务器命令配置bin目录,路径是到bin路径下配置CATALINA_HOME:路径是到根路径下Tomcat服务器目录结构:1. bin:bin目录用来存放tomcat的命令,主要有两大类一类是以.sh结尾的(linux命令),另一类是以.bat结尾的(windows命令)。- startup 用来启动tomcat- shutdown 用来关闭tomcat2. conf:conf目录主要是用来存放tomcat的一些配置文件。- server.xml可以设置端口号、设置域名或IP、默认加载的项目、请求编码- web.xml可以设置tomcat支持的文件类型- context.xml可以用来配置数据源之类的- tomcat-users.xml用来配置管理tomcat的用户与权限- 在Catalina目录下可以设置默认加载的项目3. lib:lib目录主要用来存放tomcat运行需要加载的jar包。4. logs:logs目录用来存放tomcat在运行过程中产生的日志文件,非常重要的是在控制台输出的日志。(清空不会对tomcat运行带来影响)在windows环境中,控制台的输出日志在catalina.xxxx-xx-xx.log文件中在linux环境中,控制台的输出日志在catalina.out文件中5. temp:temp目录用户存放tomcat在运行过程中产生的临时文件。(清空不会对tomcat运行带来影响)6. webapps:webapps目录用来存放应用程序,当tomcat启动时会去加载webapps目录下的应用程序。可以以文件夹、war包、jar包的形式发布应用。当然,也可以把应用程序放置在磁盘的任意位置,在配置文件中映射好就行。7. work:work目录用来存放tomcat在运行时的编译后文件,例如JSP编译后的文件。清空work目录,然后重启tomcat,可以达到清除缓存的作用。

第一个WebApp

在html中的超链接,完整的可以写成:<a href="http://localhost:8080/app01/login.html">Login</a>为了代码的更加通用,可以直接从部署的项目名开始写,前面的IP地址和端口号可以省略,但要注意省略之后是以“/”开头

Servlet

Serv表示服务器端,let表示小程序
就是sum公司制定的Web服务器和Web服务器端的java小程序之间的接口,其中有五个方法需要重写:void destroy();ServletConfig getServletConfig();String getServletInfo();void init(ServletConfig config);void service(ServletRequest request, ServletResponse response);

第一个带有Servlet的WebApp

WebAp的目录结构:最重要的:WEB-INFO文件夹、以及html文件夹、css文件夹、js文件夹等文件夹WEB-INF文件夹里面有:classes文件夹--->存放字节码文件lib文件夹------->存放程序运行所需要的库(如数据库驱动);web.xml--------->配置文件,写的是请求路径与绑定的从servlet文件(Java文件)Tomcat服务器的lib和webapp的lib目录:Tomcat服务器目录的lib是Tomcat的classpath,是全局的每一个webapp也有一个lib,相当于是项目自己的classpath,是局部的web.xml文件编写:<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>ThisIsHelloServlet</servlet-name><servlet-class>cn.qkmango.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>ThisIsHelloServlet</servlet-name><url-pattern>/hello/servlet/test</url-pattern><url-pattern>/hello/servlet</url-pattern><!--路径随意编写,但是必须以 “/”开始,这个路径是虚拟路径,这个路径是cn.qkmango.HelloServlet.class文件的代号,用户只要访问这个路径,就会执行cn.qkmango.HelloServlet.class文件对应的url-pattern可以有多个注意,url-pattern不需要以项目名开头,但是超链接需要以项目名开头--></servlet-mapping>
</web-app>       web.xml文件主要配置请求路径和Servlet类名之间的绑定关系
web.xml文件在Tomcat服务器启动阶段被解析
web.xml文件解析失败,会导致webapp启动失败
web.xml文件中的标签不能随意编写
web.xml文件中的标签也是sun公司指定的Servlet规范
一个webapp只有一个web.xml

将响应结果输出到浏览器中

将内容输出到浏览器的三个步骤:1. 解决中文乱码问题,设置内容类型和字符集因为writer是从servletResponse获取的,所以在获取之前进行设置servletResponse.setContentType("text/html;charset=UTF-8");2. 获取流对象,直接指向浏览器客户端PrintWriter writer = servletResponse.getWriter();3. 将内容输出到浏览器writer.print();/* WelcomeServlet类 */
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;//标准输出流,不需要关闭
public class WelcomeServlet implements Servlet {//实现Servlet要重写它的5个方法@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {servletResponse.setContentType("text/html;charset=UTF-8");/*** 将信息输出到浏览器上* 将HTML字符输出到浏览器上,浏览器解释执行* 获取流对象,直接指向浏览器客户端*/PrintWriter writer = servletResponse.getWriter();writer.print("<html>" +"<head><title>welcome欢迎</title></head>" +"<body><h1>welcome Page欢迎页面</h1></body>" +"</html>");}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}

编写JDBC连接到数据库

 注意把jar包导入到对应的位置,最好是能够检查一下,如果使用了数据库连接池,那么同时也要导相应的jar包,还有数据库的驱动jar包。Eclipse中项目默认是在:                                             F:\JAVA\EclipseWorkSpace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps中但是可以更改默认配置。

Servlet生命周期

生命周期?一个程序从创立到销毁经历的所有过程Servlet对象的生命周期是谁来管理的?Servlet对象的生命周期,包括Servlet对象方法的调用,javaweb程序员是无权干涉的。Servlet对象从最初创建到方法的调用及对象的销毁,整个过程都是web容器(Web Container)来管理的。默认情况下,Servlet对象在web服务器启动阶段不会被实例化。若希望在web服务器启动阶段实例化Servlet对象:需要在配置文件servlet中加上‘<load-on-startup>自然数<load-on-startup>’,自然数越小,优先级越高)描述Servlet对象生命周期*****1、用户在地址栏输入URL:http://localhost:8080/adhhqk/uqidqk2、web容器截取请求路径:/adhhqk/uqidqk3、web容器在上下文中找请求路径/adhhqk/uqidqk对应的Servlet对象4、若没有找到对应的Servlet对象4.1、通过web.xml文件中相关的配置信息,得到请求路径/uqidqk对应的Servlet完整类名4.2、通过反射机制,调用Servlet类的无参数构造方法完成Servlet对象的实例化4.3、web容器调用Servlet对象的init方法完成初始化操作4.4、web容器调用Servlet对象的service方法提供服务5、若找到对应的Servlet对象5.1、web容器直接调用Servlet对象的service方法提供服务6、web容器关闭的时候/webapp重新部署的时候/该Servlet对象长时间没有用户再次访问的时候,web容器会将该Servlet对象销毁,在销毁该对象之前,web容器会调用Servlet对象的destroy方法,完成销毁之前的准备。总结:Servlet类的构造方法只执行一次Servlet对象的init方法只执行一次Servlet对象的service方法,只要有用户请求一次,则执行一次Servlet对象的destroy方法只执行一次注意:init方法执行的时候,Servlet对象已经创建好了。destroy方法执行的时候,Servlet对象还没有被销毁,处于即将销毁。Servlet对象是单例,但是不符合单例模式,只能称为伪单例。真单例的构造方法是私有化的。Tomcat服务器是支持多线程的,所以Servlet对象在单实例多线程的环境下运行的。那么Servlet对象中若有实例变量,并且实例变量涉及到修改操作,那么这个Servlet对象一定会存在线程安全问题,不建议在Servlet对象中使用实例变量,尽量使用局部变量。Servlet对象实例化之后存储到哪里了?大多数的Web容器都是将该Servlet对象以及对应的url-pattern存储Map集合中了,在web容器中有这样一个Map集合Map<String, Servlet>key             value--------------------------------------/login          LoginServlet对象的引用/delete         DeleteServlet对象的引用/insert         InsertServlet对象的引用服务器启动阶段解析的web.xml文件,做了什么?        在web容器中有这样一个集合:Map<String, String>key                  value---------------------------------------------------------/login          login对应的全类名/delete         delete对应的全类名/insert         insert对应的全类名实际上,服务器启动时就会解析web.xml文件,并且将解析的数据存放在Map集合中,当在浏览器中输入请求的路径时,web容器在容器里去找请求路径对应的Servlet对象,如果没有找到,**实际上不是去web.xml文件中找此路径对应的完整类名,而是去此Map集合中查找Servlet接口中的方法写什么代码?何时使用?1. 无参构造方法【以后就不需要考虑构造方法了,尽量别动构造方法】2. init():无参构造方法和`init()`,两个方法执行时间几乎是相同的,都只执行一次若系统要求对象在创建时刻执行一段特殊的程序,这段程序尽量写到init()方法中为什么不建议将代码写到构造法中呢?存在风险!当程序员编写构造方法的时候,可能会导致无参构造方法不存在Servlet中的`init()`方法是SUN公司为程序员专门提供的一个初始化时刻,若希望初始化时刻执行一段程序,这个程序可以编写在`inti()`方法中,将来会被自动调用3. service()这个方法是必然重写的,因为这个方法需要完成业务逻辑的处理,请求的处理,以及完成响应4. destroy()这个方法是为程序员提供的一个特殊时刻,这个特殊时刻被成为对象销毁时刻;若希望在销毁时刻执行一段特殊代码,需要将这段代码写到`destroy()`方法中,会被自动调用

ServletConfig接口

1. 【作为了解】Apache Tomcat服务器实现了Servlet规范,Tomcat服务器写了一个ServletConfig接口的实现类,实现类的完整类名是`org.apache.catalina.core.StandardWrapperFacade`2. Javaweb程序员在编程的时候,一直是面向ServletConfig接口去完成调用的,不需要关心具体的实现类,只需要学习ServletConfig接口有哪些可以使用的方法。- webapp放到Tomcat服务器中,ServletConfig的实现类是:`org.apache.catalina.core.StandardWrapperFacade`- webapp放到JBOSS服务器中,ServletConfig的实现类可能是另外一个类名了3. 怎么理解Tomcat服务器?Tomcat服务器是一个实现了Servlet规范和JSP规范的容器ServletConfig到底是什么?ServletConfig是一个Servlet对象的配置信息对象,ServletConfig对象中封装了一个Servlet对象的配置信息Servlet对象的配置信息在web.xml文件中一个Servlet对象对应一个ServletConfig对象对象,100个Servlet对象对应100个ServletConfig对象如何在`service()`方法中使用`init()`方法中的`servletConfig`参数对象 在`init()`方法中完成:局部变量servletConfig赋值给实例变量servletConfig:this.config = config;在`getServletConfig()`,提供公开的get方法,目的是供子类使用,只需要修改return返回值即可:return config;ServletConfig接口中的方法String `getInitParameter(String name)` 通过name,获取初始化参数name对应的valueEnumeration `getInitParameterNames()` 获取初始化参数的name集合。遍历用hasmoreElements();String `getServletName()` 获取servletName,`<servlet-name>servletName</servlet-name>`ServletContext `getServletContext()` 获取ServletContext【Servlet上下文】对象`<init-param>`标签,初始化参数`<init-param>`标签是初始化参数,定义在`<servlet>`标签中`<init-param>`标签内还有`<param-name>`表示key,`<param-value>`表示value`<init-param>`定义的参数属于某一个 ServletString value = servletConfig.getInitParameter(name)获取的就是`<init-param>`中的参数这些信息封装在ServletConfig对象中

ServletContext接口

1. `javax.servlet.ServletContext`接口,Servlet规范2. Tomcat服务器对ServletContext接口的实现类完整类名是:`org.apache.catalina.core.ApplicationContextFacade`javaweb程序员只需要面向ServletContext接口调用方法即可,不需要关心Tomcat具体的实现ServletContext到底是什么?什么时候被创建?什么时候被销毁?创建几个?    - ServletContext被译为:Servlet上下文- 一个webapp只有一个web.xml文件,web.xml文件服务器启动阶段被解析- 一个webapp只有一个ServletContext对象,ServletContext对象在服务器启动阶段被实例化- ServletContext在服务器关闭的时候被销毁- ServletContext对应的是web.xml文件,是web.xml文件的代表- ServletContext是所有Servlet对象四周环境的代表,被所有Servlet共享- 所有用户若想共享同一个数据,可以将数据放到ServletContext对象中(写到web.xml文件中,或后期通过方法添加)- 一般放到ServletContext对象中的数据不建议涉及到修改操作的,以为ServletContext是多线程共享的一个对象,修改的时候会存在线程安全问题 ServletContext接口中有哪些常用方法    - void `setAttribute(String name, Object object)` 向ServletContext中添加数据- Object `getAttribute(String name)` 从ServletContext中获取数据- void `removeAttribute(String name)` 从ServletContext中移除数据- String `getInitParameter(String name)` 从ServletContext中获取name所对应的value初始化参数(\<context-param>标签中)- Enumeration `getInitParameterNames()`从ServletContext中获取name所对应的value初始化参数(\<context-param>标签中),遍历用hasmoreElements()- String `getRealPath(String path)` 获取文件绝对路径    ServletContext范围可以完成跨用户传递数据`<context-param>`上下文参数,定义的参数属于全局,所有Servlet共享`<param-name>`表示参数的name(key)`</param-name>``<param-value>`name所对应的value`</param-value>``<context-param>`
- 这些参数信息封装在ServletContext对象中ServletContext application = config.getServletContext();application.getRealPath("/资源路径");

Servlet、ServletConfig、ServletContext之间的关系

- 一个Servlet对应一个ServletConfig对象
- 所有的Servlet共享一个ServletContext对象

欢迎页面

欢迎页面是怎么设置的?假设在webapp/html目录下创建welcome.html,想让welcome.html作为整个webapp的欢迎页面,应该在web.xml文件中添加如下标签欢迎页面可以设置多个,越靠上越优先,当前面的欢迎页面找不到时才使用后面的欢迎页面<!--将welcome.html页面作为欢迎页面--><!--注意开头没有“/”--><welcome-file-list><welcome-file>html/welcome.html</welcome-file><welcome-file>welcome2.html</welcome-file></welcome-file-list>
欢迎页面可以是任何一种web资源欢迎页面不仅可以是html文件,也可以时任何一种web资源,如Servlet欢迎页面有全局配置和局部配置全局配置:`CATALINA_HOME/conf/web.xml`局部配置:`CATALINA_HOME/webapps/webapp/WEB-INF/web.xml`若有局部配置,优先使用局部配置(就近原则)若在web目录中有index.html、index.htm、index.jsp文件,这些都是默认的欢迎页面,都在全局配置中已经配置过了,即全局配置中,默认以这些文件为欢迎页面

常见错误代码

-404 Not Found 资源未找到,一般是路径写错。
-500 Server Inner Error 服务器内部错误,一般都是服务器Java程序出现异常404和500是HTTP协议状态码,是W3C制定的,正常响应的HTTP协议状态码是200    可以在web.xml中添加错误页面,出现错误跳转到指定页面。<error-page><error-code>404</error-code>   <location>/errorPage/404.html</location></error-page>

GenericServlet适配器

缺省适配器目前我们所有的Servlet类直接实现了javax.servlet.Servlet接口,但是这个接口中有很多方法但是可能方法不需要。导致直接实现Servlet接口的代码丑陋,所以有必要在中间添加一个适配器,以后所有的Servlet类不再直接实现Servlet接口,而而是去继承适配器适配器可以让代码优雅之外,我们还可以在适配器中提供大量的方法,子类继承之后,可以在子类中直接使用,方便编程自定义GenericServlet类(适配器):    问题:为了让适配器类中`init(ServletConfig)`中的代码生效,而被final修饰限制不被重写,那么怎么在初始化时刻执行一段代码呢?解决:`init()`方法为`init(ServletConfig)`同名的重载方法,原本的`init(ServletConfig)`方法为了使其中的代码不被覆盖重写而失效,所以添加了`final`修饰,但是使得`init(ServletConfig)`无法重写而过于局限,所以我们扩展一个同名的`init()`方法供程序员重写,`init()`会被`init(ServletConfig)`调用,这样我们只需要重写`init()`即可,若在Servlet初始化时刻需要执行一段特殊的代码,建议重写此无参数的`init()`方法   SUN提供的GenericServlet类(适配器):SUN公司已经为我们准备了官方的GenericServlet类-->`javax.servlet.GenericServlet`

HTTP协议

什么是HTTP协议?- 超文本传输协议- 浏览器和服务器之间的一种通讯协议- 该协议时W3C负责制定的,其本质上就是数据传送格式。浏览器和服务器都必须按照这种格式接收与发送数据1.0和1.1版本区别1.0在应对有图片的资源的时候需要跑两趟,而1.1只需要一趟状态码:1xx:请求已到达服务器,但未完成,需要再次请求2xx:请求已到达服务器,并且已完成3xx:服务器内部资源重定向4xx:资源找不到5xx:服务器内部异常,代码异常手动设置状态码:只显示状态码:response.setStatus(xxxx);设置状态码的同时加上提示语句:response.sendError(xxx,"提示");HTTP协议包括几部分?请求协议:- 请求行:请求方式 URI 协议版本号 `POST /webapp10/login HTTP/1.1`- 请求报头- 空白行- 请求体响应协议:- 状态行:协议版本号 状态码 描述信息- 响应报头- 空白行- 响应体空白行是专门用来分隔消息报头和请求体的响应协议中的状态码:404-资源未找到  500-服务器内部错误 200-响应成功,正常结束响应报头常见使用:使用Location进行跳转,需要先设置服务器状态码为302response.setStatus(302);--->response.setHeader("Location","跳转网址");使用refresh进行延时跳转response.setHeader("Refresh","时间;跳转网址");使用Content-Type显示服务器图片(注意图片放在src下)response.setHeader("Content-Type","jpg/image/...");Web中读取文件使用类加载器:this.getClass().getClassLoader().getResourceAsStream("文件");web中输出流使用:ServletOutputStream out = response.getOutputStream();开始边读边写使用Content-Disposition下载内容response.setHeader("Content-Disposition","attachment;filename=文件名");然后流操作注意:ServletOutputStream out = response.getOutputStream();字节流PrintWriter out = response.getWriter();字符流注意:这两个流不能同时使用。get请求和post请求:什么情况下浏览器发送的请求是GET请求,什么情况下浏览器发送的请求是POST请求?只有当使用表单form,并且method属性设置为"post",才是POST请求方式,其余剩下的所有请求都是GET请求GET请求和POST请求有什么区别?GET请求在请求行上提交数据,格式`uri?name=value&name=value`,这种提交方式最终提交的数据会显示在浏览器地址栏上POST请求在请求体中提交数据,相对安全,提交格式`name=value&name=value`,这种提交方式最终不会显示在浏览器地址栏上GET请求在请求行上提交数据,所以GET请求提交的数据长度有限制POST请求在请求体中提交数据,所以POST请求提交的数据没有长度限制【POST可以提价大数据】GET请求只能提交字符串数据,POST请求可以提交任何类型的数据,包括视频...,所以文件上传必须使用POST请求GET请求最终的结果,会被浏览器缓存收纳,而POST不会被缓存收纳GET请求和POST请求应该如何选择?- 有敏感数据 POST- 传送的数据不是普通字符串 POST- 传送的数据非常多 POST- 这个请求是为了修改服务器端资源 POST- GET请求多数情况下是从服务器中读取资源,这个读取的资源在短时间内不会发送变化,所以GET请求最终的结果会被浏览器缓存起来- POST请求是为了修改服务器端的资源,而每一次修改结果都是不同的,最终结果没有必要被浏览器缓存    浏览器将资源缓存后,缓存的资源是和某个特定的路径绑定在一起的,只要浏览器再发送这个相同的请求路径,这个时候浏览器就会去缓存中获取资源,不再访问服务器,以这种方式降低服务器的压力,提高用户体验。但是有的时候我们并不希望走缓存,希望每一次重新访问服务器,可以在请求路径后面添加时间戳,例如:`http://ip:port/oa/system/logout?timetamp=1234564635423`    怎么获取毫秒值:new Date().getTime();

HttpServlet

SUN公司为我们提供了一个类来解决判断前后端请求方式是否一致的类:`javax.servlet.http.HttpServlet`我们写的XxxServlet继承HttpServlet后,后端需要的是什么请求,那么我们就重写对应的`doPost()`/`doGet()`方法`doPost()`/`doGet()`方法内就是我们的业务代码,`doXXX()`可以看作`main()`方法代码不在`service()`内编写了,不需要重写`service()`方法HttpServlet中重载的两个`service()`方法并不需要也没有理由去重写这两个方法当浏览器发送的请求方式和后台处理方式不同时,会出现一个错误,代号:405   自定义的HttpServlet(帮助理解原理)
public class HttpServlet extends GenericServlet {/***  此方法为原始service()方法,方法内将ServletRequest、ServletResponse强转为带有http的接口*  然后调用重载的service(HttpServletRequest, HttpServletResponse)方法*  所以此方法我们无需进行重写*/@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) res;service(request,response);}/*** 此方法获取请求方式后进行判断,* 如果是GET请求就执行doGet()* 如果是POST请求就执行doPost()* 此方法没有理由重写,只需要将业务代码写在doGet()或doPost()方法中即可*/public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {String method = request.getMethod();if("POST".equals(method)) {doPost(request, response);} else if("GET".equals(method)) {doGet(request, response);}}/*** 我们需要什么请求时,子类继承此父类就应当重写对应的doGet()或者doPost()方法之一* 在doGet()或者doPost()方法内写业务代码,即将原来的service()内的业务代码写到doXXX()中*/public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setContentType("text/html;charset=UTF-8");response.getWriter().print("应当发送GET请求");throw new RuntimeException("应当发送GET请求");}public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setContentType("text/html;charset=UTF-8");response.getWriter().print("应当发送POST请求");throw new RuntimeException("应当发送POST请求");}
}
此时编写了一个方法继承了自定义的HttpServlet
- 假设前端发送的是POST请求`service(ServletRequest, ServletResponse)` 将两个参数强转为带有Http的接口,之后执行`service(HttpServletRequest, HttpServletResponse) `获取请求方式POST并通过判断执行重写的doPost()方法`doPost(HttpServletRequest, HttpServletResponse)` 执行业务代码
- 假设前端发送的是GET请求`service(ServletRequest, ServletResponse)` 将两个参数强转为带有Http的接口,之后执行`service(HttpServletRequest, HttpServletResponse)`获取请求方式GET并通过判断执行未被重写的doGet()方法`doGet()` 报错,将错误信息输出到控制台和前端页面

模版方法设计模式(templateMethod)

模版方法,定义核心算法骨架,具体的实现步骤延迟到子类中完成
public abstract class Person {/*** templateMethod是一个模版方法,定义核心算法骨架,具体的实现步骤延迟到子类中完成* 算法为了受到保护,所以模版方法一般都使用final修饰,不被重写* 核心算法骨架不需要每一次在具体的类中编写了,这个核心算法只在模版方法中编写一次* 算法步骤改变,只要更改模版就可以,同时也避免了算法在每一个具体的类中编写而冗余*/public final void templateMethod() {//核心算法骨架do1();do2();do3();}/*** 这就是具体的实现,这个具体的步骤可以延迟到子类中完成(经子类继承实现)* 这个方法通常是抽象方法*/protected abstract void do1();protected abstract void do2();protected abstract void do3();
}    模版方法设计模式属于行为行设计模式
模版方法有一个特点:`doXXX()`模板方法设计模式的主要作用:1. 核心算法得到保护2. 核心算法得到复用3. 在不改变算法的前提下,却可以重新定义算法步骤的具体实现模板方法设计模式的经典例子:- Servlet规范中的HttpServlet- HttpServlet就是一个非常典型的模板方法设计模式- HttpServlet是一个模板类- 其中的service(HttpServletRequest, HttpServletResponse)方法是典型的模板方法,该方法中定义了核心算法骨架,doGet()、doPost()......具体的实现细节延迟到子类中完成

MVC架构

生活中的三层架构:(服务员,厨师,采购)优点:各司其职,互不干扰,工作效率高,任意环节出现问题有相应的责任人,与他人无关。缺点:员工越多,成本越高。软件中的三层架构:(表示层,业务逻辑层,数据访问层)表示层:与用户交流的页面,相当于服务员业务逻辑层:实现逻辑控制,相当于厨师数据访问层:与数据库交互,相当于采购优点:1)结构清晰,降低耦合2)可维护性高,可扩展性高3)有利于团队开发4)适应需求变化缺点:1)代码量增加2)降低系统性能M:model     V:view        C:controllerMVC与三层架构的关系表示层:view,controller业务逻辑层:controller数据访问层:model使用MCV搭建项目目录表示层:HTML或者JSP放到WebContent中,com.ujiuye.servlet业务逻辑层:com.ujiuye.servlet,com.ujiuye.service数据访问层:com.ujiuye.dao实体类:com.ujiuye.entity工具类:com.ujiuye.util测试类:com.ujiuye.test

HttpServletRequest接口

1. HttpServletRequest是一个接口,Servlet规范中重要的接口之一2. 继承关系:public interface HttpServletRequest extends ServletRequest3. HttpServletRequest接口的实现类时Web容器负责的,Tomcat服务器有自己的实现。所以程序员还是只需要面向HttpServletRequest接口调用方法即可,不需要关心具体的实现类4. HttpServletRequest这个对象中封装了哪些信息?封装了HTTP请求协议的全部内容:- 请求方式- URI- 协议版本号- 表单提交的数据......
5. HttpServletRequest一般对象的名字叫做:request;HttpServletRequest对象代表一次请求,一次请求执行一次service()方法,对应一个request对象,100个请求对应100个request对象,所以request对象的生命周期是短暂的;什么是一次请求?到目前为止,我们可以这样理解一次请求:在网页上点击超链接,到最终网页停下来,这就是一次完整的请求;(后面学习重定向,浏览器会自动跳转到其他地址,会重新发送新的请求,这句话就不正确了)6. 获取用户信息,表单提交的这些数据被自动封装在request对象中了表单数据是这样的格式提交的,POST请求,在请求体中提交,数据格式: username=admin&password=123&sex=boy&interest=sport&interest=music&grade=gz&introduce=student表单提交的数据会自动封装到request对象中,request对象中有一个Map集合,存储这些数据:Map<String, String[]>key          value(value是一维数组)-------------------------------username     {"admin"}password     {"123"}sex          {"boy"}interest     {"sport","music"}grade        {"gz"}introduce    {"IAmAStudent"}HttpServletRequest中常用的方法:/*获取浏览器提交的数据*/String getParameter(String name) 获取key对应的一维数组的首元素Map getParameterMap() 获取request对象中的Map集合Enumeration getParameterNames() 获取所有的Map集合中所有的keyString[] getParameterValues(String name) 返回String数组,数组包含key对应的多个value值/*获取路径、URL、URI、IP*/String getContextPath() 获取上下文路径(web项目根路径)String getMethod() 获取浏览器请求方式String getRequestURI() 获取请求的URIStringBuffer getRequestURL() 获取请求的URLString getServletPath() 获取请求的ServletPath,即servlet对应的请求路径String getRemoteAddr() 获取客户端IP地址/*从一次请求对应的HttpServletRequest对象范围中增删查数据*/Object getAttribute(String name) 从此次请求对应的request对象范围中获取数据void setAttribute(String name, Object o) 从此次请求对应的request对象范围中存储数据void removeAttribute(String name) 从此次请求对应的request对象范围中删除数据/*请求转发器*/RequestDispatcher getRequestDispatcher(String path) 获取请求转发器请求转发:1. 获取请求转发器对象、2. 调用请求转发器的`forward()`方法即可完成转发/*/a路径对应AServlet,/b路径对应BServlet,通过request对象的getRequestDispatcher方法获取请求转发器对象,然后调用请求转发器对象的forward方法进行转发以下代码是从AServlet转发到BServlet*///获取请求转发器,以下转发器指向了BServlet,调用请求转发器的forward()RequestDispatcher requestDispatcher = request.getRequestDispatcher("/b");requestDispatcher.forward(request,response);//合并:request.getRequestDispatcher("uri").forward(request,response);/*编码*/void setCharacterEncoding(String env) 覆盖此请求正文中使用的字符编码的名称/**/HttpSession getSession() 返回与此请求关联的当前会话,或者如果该请求没有会话,则创建一个。Cookie[] getCookies() 返回一个数组,其中包含Cookie 客户端与此请求一起发送的所有对象。关于范围对象的选择:  ServletContext 应用范围极大,可以跨用户传递数据,整个webapp只有一个ServletContext对象ServletRequest请求范围小,只能在同一个请求中传递数据【跨Servlet传递数据,需要使用请求转发技术】优先选择使用ServletRequest传递数据  文件上传:就是复制一份源文件到指定的位置去:步骤:1、表单的method属性的值必须是post,在表单上加上enctype,值为multipart/form-data2、在Servlet上加上@MultipartConfig3、写代码://先获取上传的文件对象Part part = request.getPart("表单file中的name");//找到上传的文件的文件名和扩展名String header = part.getHeader("Content-Disposition");//获取文件名String fileName = header.substring(header.indexOf("filename")+10,header.length()-1)//指定上传位置String path = "位置";//判断该文件夹是否存在,如果不存在,则创建夹    File file = new File(path);if(!file.existe()){file.mkdir}//防止文件重名,可以使用UUID工具类生成随机32位随机字符串part.write(path+"/"+UUID.randomUUID()+fileName);

项目中出现乱码问题

数据保存过程中的乱码:- 数据保存到数据库表中的时候,数据出现乱码- 导致数据保存过程中的乱码包括以下两种情况:- 前一种情况:在保存之前,数据本身就是乱码,保存到数据库表中的时候一定是乱码- 第二种情况:保存之前,数据不是乱码,但是由于数据库本身数据库不支持简体中文,保存之后出现乱码数据展示过程中的乱码:最终显示到网页上的数据出现中文乱码第一种情况:经过执行Java程序之后,Java程序负责向浏览器响应的时候,中文乱码解决:Java程序中设置响应的内容类型,以及对应的字符字符集response.setContentType("text/html;charset=UTF-8");第二种情况:没有经过Java程序,直接访问的是html页面解决:在html文件中使用<meta content="text/html;charset=utf-8">或者<meta charset="utf-8">数据传递过程中的乱码:通用方法://获取乱码字符String dname = request.getParameter("name");//将乱码字符通过错误的ISO-8859-1编码方式重新还原回去byte[] bytes = dname.getBytes("ISO-8859-1");//再通过正确的编码方式进行解码value = new String(bytes, "UTF-8");仅支持POST请求://设置字符编码方式request.setCharacterEncoding("UTF-8");仅支持GET:修改CATALINA_HOME/conf/server.xml文件,加上URLEncoding="UTF-8"属性,设置请求行上的编码方式,解决GET请求乱码<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" URLEncoding="UTF-8"/>//Connector里面还可以编写哪些属性:帮助文档:CATALINA_HOME/webapps/docs/config/http.html//eg:port-端口号;maxThreads-最高支持线程数量默认200;URIEncoding-请求行上的编码方式URLencode:是将字符通过某种字符集进行编码后,再使用百分号编码.如字符通过UTF-8字符集进行编码后得到的二进制文件,然后将二进制转化为16进制,在每一个字符前面加上%作为分隔UTF-8                                          百分号编码"销售部"  ------> E9 94 80 E5 94 AE E9 83 A8 ------> %E9%94%80%E5%94%AE%E9%83%A8

Servlet线程安全问题

Servlet是单实例多线程环境下运行的Servlet对象只有一个,被多个线程共享;new出来的对象在堆空间,所有线程共享一个堆;Servlet怎么解决线程安全问题:1. 不使用实例变量,尽量使用局部变量2. Servlet是单例的,所以剩下的方式只能考虑使用`synchronized`,线程同步机制

转发和重定向

转发:request.getRequestDispatcher("/b").forward(request,response);
重定向:response.sendRedirect(request.getContextPath()+"/b");转发和重定向的区别:- 相同点:都可以完成资源的跳转- 不同点:- 转发是request对象触发的,服务器内部进行转发- 重定向是response对象触发的,要将重定向的路径相应给浏览器- 转发是一次请求,浏览器地址栏上地址不变- 重定向是两次请求,浏览器地址栏上的地址发生变化- 重定向路径需要加项目名(webapp跟路径web目录)- 转发是在本项目内部完成资源的跳转- 重定向可以完成跨app跳转,例如可以跳转到`https://www.baidu.com`什么时候采用转发,什么时候采用重定向?大部分情况下都使用重定向- 若想完成跨app跳转,必须采用重定向- 重定向可以解决浏览器的刷新问题- 若在上一个资源中向request范围中存储了数据,希望在下一个资源中从request范围中取出,必须使用转发重定向原理是什么?response.sendRedirect("/jd/login");程序执行到以上代码,将请求路径`/jd/login`反馈给浏览器,浏览器又向web服务器发送了一次全新的请求:/jd/login浏览器地址栏上最终显示的地址是:/jd/login

重定向解决页面刷新问题

如果使用转发:浏览器只进行一次请求,如果此时浏览器进行刷新,浏览器刷新的是最后一次请求,即提交表单的请求,此时多次刷新浏览器,那么就会请求多次,就会执行多次Servlet,就会多次连接数据库插入数据,导致数据重复插入如果使用重定向:服务器返回重定向的地址(success.html),浏览器就会请求新的地址,一共有两次请求:提交表单的请求和重定向的请求此时如果浏览器多次刷新,那么请求的也是重定向的success.html静态页面,不会因为刷新而导致多次提交表单

Cookie

Cookie是什么?- Cookie可以保存会话状态,但是这个会话状态是保留在客户端上的- 只要Cookie清除,或者Cookie失效,这个会话状态就没有了- Cookie是保存在浏览器客户端上的- Cookie可以保存在浏览器的缓存中,浏览器关闭Cookie消失- Cookie可以用保存在客户端硬盘文件中,浏览器关闭Cookie还在,除非Cookie消失    创建Cookie:服务器创建Cookie并发送给浏览器//创建cookieCookie cookie = new Cookie(String name, String value);//设置Cookie有效期cookie.setMaxAge(60*60*60);//设置Cookie绑定的路径cookie.setPath("/webapp19/user");//将cookie发送给浏览器response.addCookie(cookie);Cookie绑定路径:在默认情况下,未设置Cookie绑定路径的Cookie,会绑定当前访问路径的"上级路径/",当浏览器访问这个路径,以及以这个路径作为根路径的地址时都会发送Cookie给服务器。`cookie.setPath();`来设置此Cookie绑定的访问路径Cookie有效时长:`cookie.setMaxAge(int expiry)`- 参数是一个整数- 值为正数,以秒为单位指定Cookie的最长期限,Cookie存储在硬盘文件当中;- 值为负数,则此Cookie在关闭此窗口页面后即失效;- 如果为零,则删除此Cookie;

HttpSession

Session概述:1. Session表示会话,不止是在javaweb中存在,只要是web开发,都会有这种机制2. 在java中会话对应的类型是:javax.servlet.http.HttpSession 简称session/对话 3. Cookie可以将会话状态保存在客户端,而HttpSession可以将会话状态保存在服务器端4. HttpSession对象是一个会话级别的对象,一次会话对应一个HttpSession对象5. 在会话进程中,web服务器一直为当前这个用户维护着一个会话对象HttpSession6. 在web容器中,维护了大量的HttpSession对象,换句话说,在web容器中应该有一个“Session”列表思考:为什么当前会话中的每一次请求都可以获取到属于自己的Session会话对象?什么是一次会话?- 一般可以这样理解:用户打开浏览器,在浏览器上发送多次请求,直到最终浏览器关闭,表示一次完整的回话。- 本质上理解:Session对象创建到最终超时销毁,才是真正意义的一次会话;因为即使浏览器关闭,可以通过重写URL的方式从其他电脑其他浏览器同样使用这个Session对象。   获取Session对象:HttpSession session = request.getSession(无参数默认为true);注意:request.getSession(boolean)需要一个boolean类型的参数当参数为true(无参默认true)时,session存在则返回;如果session不存在,则创建一个新的session对象并返回当参数为false时,session存在则返回;如果session不存在,则返回nullSession实现原理:1. 浏览器发送请求,服务器对应的Servlet**首次调用**`request.getSession(true);`方法1.1 服务器会创建一个Session对象,该对象代表一次会话,同时生成一个对应的Cookie对象,并且Cookie对象的name是JSESSIONID,Cookie的value是32位长度的字符串1.2 服务器将Cookie的value和HttpSession对象绑定到session列表中(Map集合)1.3 服务器将Cookie发送到浏览器客户端,浏览器客户端将Cookie保存到缓存中(只要浏览器不关闭,Cookie不会消失)2. 浏览器再次发送请求,会自动提交缓存当中的Cookie2.1 当服务器Servlet**再次调用**`request.getSession();`方法时获取Session对象2.2 服务器接收到Cookie,验证Cookie的name为JSESSIONID,然后获取该Cookie的value2.3 通过Cookie的value去session列表(Map集合)中检索对应的HttpSession对象  Session对象在什么时候销毁?1. web系统中引入了session超时的概念2. 当一段时间没有用户再访问session对象,此时session对象超时,web服务器自动回收session对象3. 设置Session对象失效时间(两次请求之间的最大时间间隔),优先级 A > B > CA:通过Java代码实现,单位秒HttpSession session = request.getSession();session.setMaxInactiveInterval(60*60);B:修改项目的web.xml文件,单位分钟<session-config><session-timeout>60</session-timeout></session-config>C:修改Tomcat默认配置,单位分钟,默认30分钟,CATALINA_HOME/conf/web.xml<session-config><session-timeout>30</session-timeout></session-config>HttpSession中常用方法:void setAttribute(String name, Object value) 向会话范围中存储数据Object getAttribute(String name) 从会话范围中获取数据void removeAttribute(String name) 从会话范围中移除某个数据void invalidate() 销毁session对象void setMaxInactiveInterval(int interval) 设置session对象失效时间ServletContext、HttpSession、HttpServletRequest对比:1. 以上都是范围对象:`ServletContext application` 是应用范围`HttpSession session` 是会话范围`HttpServletRequest request` 是请求范围2. 三个范围的大小 application > session > request 3. application完成跨会话(用户)共享数据;session完成跨请求共享数据,但是这些请求必须在同一个会话当中;request完成跨Servlet共享数据,但是这些servlet必须在同一个请求当中(请求转发)4. 使用原则:由小到大尝试,优先使用小范围注意:1. HttpSession对象关联的这个Cookie的name是比较特殊的,在Java中就叫做:JSESSIONID2. 浏览器禁用Cookie会出现什么问题?怎么解决?- 浏览器禁用Cookie,则浏览器缓存中不再保存Cookie- 导致在同一个会话中,无法获取到对应的会话对象- 禁用Cookie之后,每一次获取的会话对象都是新的- 浏览器禁用Cookie之后,若还想拿到对应的Session对象,必须使用URL重写机制怎么重写URL:```http://localhost:8080/webapp23/testSession;jsessionid=384A8D1CE7821C76EDC445F7D029C46A```重写URL会给编程带来难度/复杂度,所以web站点是不建议禁用Cookie使用重写URL,即使换浏览器换电脑,只要在一定时间内访问的是同一个jsessionid,就可以得到同一个Session对象3. 浏览器关闭后,服务器端对应的session对象会被销毁吗?- 浏览器关闭后,服务器不会销毁session对象;因为B/S架构的系统基于HTTP协议,而HTTP协议是一种无连接/无状态的协议- 什么是无连接/无状态?请求的瞬间浏览器和服务器之间的通道是打开的,请求响应结束后,通道关闭;这样做的目的是降低服务器的压力

路径编写

超链接:<a href="/项目名/资源路径"</a>form表单:<form action="/项目名/资源路径"</form>;; 重定向:response.sendRedirect("/项目名/资源路径");转发 :request.getRequestDispatcher("/资源路径").forward(request,response);欢迎页面 :<welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>WelcomeServlet</welcome-file></welcome-file-list>Servlet 路径:<servlet><servlet-name>hello</servlet-name><servlet-class>cn.qkmango.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/资源路径</url-pattern></servlet-mapping>Cookie 设置path:cookie.setPath("/项目名/资源路径");ServletContext:this.getServletConfig();ServletConfig config = getServletConfig();ServletContext context = config.getServletContext();//context.getRealPath("/WEB-INF/classes/db.properties")等于以下;context.getRealPath("/资源路径");

url-pattern的编写方式

一个Servlet可以编写多个url-pattern
精确匹配:<url-pattern>/system/hello</url-pattern><url-pattern>/user</url-pattern>
扩展匹配:<url-pattern>/user/*</url-pattern>
后缀匹配:<url-pattern>*.action</url-pattern><url-pattern>*.do</url-pattern>
全部匹配:<url-pattern>/*</url-pattern>

Servlet3.0注解

注解:Servlet3.0和JDK1.5及以后的版本才能使用
最简单的注解@WebServlet("/资源名")--->相当于url-pattern,"/资源名"指向了注解的这个Servlet;多种数据的配置@WebServlet(url-Patterns = {"资源名1","资源名2","资源名3"},loadOnStartup = 0,initParams = {@WebParams(name = "",value = ""),@WebParams(name = "",value = "")}....)注意:同一个Servlet,要么使用web.xml文件配置,要么使用注解配置,但是不能使用两种方式同时配置。

XML

一种可扩展标记语言
XML文件的格式要求1)第一行必须是版本申明等信息2)有且仅有一个根标签3)不区分大小写,推荐使用小写4)自定义的标签不能是关键字5)标签之间必须正确嵌套6)标签名开头不能是数字7)标签可以有属性:属性名=”属性值”XML的作用1)配置文件2)结构化存储数据3)数据交换(典型应用:AJAX)dom4j解析XML文件  先导包再使用SAXReader将文件读成Document:Document document = reader.read("xxx.xml");获取根标签Element root = document.getRootElement();获取子标签List<Element> list = root.elements();循环获取子标签,再获取内容,获取内容用e.element("标签").getText();获取标签里面的属性用e.attributeValue("属性名")XPath解析XML文件:XPath可以用来确定XML文档中某部分位置,它基于dom4j。使用之前先导包还是先使用SAXReader将文件读成Document:  Document document = reader.read("xxx.xml");再使用语法(查文档)

JSP

Java Server Page:Java服务器页面,动态网页。Java可以直接写在这个页面上。JSP文件的执行流程:jsp文件被第一次访问的时候:jsp文件翻译成java文件,再编译成字节码文件,执行字节码文件。 通过查看编译后的字节码发现:JSP实际上就是一个Servletjsp文件未被修改第N次访问:直接执行字节码文件jsp与Servlet的区别:1、JSP主要功能是给用户看的页面,Servlet是控制器2、JSP被Tomcat翻译成java文件时直接赋予了九大内置对象,Servlet没有3、JSP是一个简化版的Servlet,功能有限。Servlet功能更加全面4、JSP不算一个纯粹的Java类,Servlet是一个纯粹的Java类JSP页面组成:1、HTML标签及其内容2、Java代码第一种:脚本(脚本的内容被翻译到了_jsp方法的内部,因此脚本中不能定义java方法)语法:<% java代码 %>第二种:表达式(将数据输出到浏览器上)语法:<%=要输出的数据%>第三种:声明语法:<%! java代码 %>3、JSP指令三大指令:page,include,taglib;语法:<%@ 指令 指令内容%>第一种:page指令(页面描述)language:当前页面的脚本语言contentType:页面响应体的编码格式pageEncoding:页面的编码格式import:导包errorPage:错误跳转指定eg:   <%@ page language="java" contentType="text/html;charset=utf-8" pageEncoding="utf-8" errorPage="xxx.jsp" %>第二种:include(包含)注意:使用include指令包含进来的JSP页面,是不会被翻译的(先把所有的合并在一起再编译)eg:<%@ include file="xxx.jsp"  %>第三种:taglib指令(引入其他工具)eg:<%@ taglib uri="xxx/jstl/core" prefix="c" %><%@ taglib uri="xxx/jstl/functions" prefix="fn" %>4、注释:要注意的是jsp本身的注释<%--内容--%>不会被翻译到java代码中,而其他的注释会

EL表达式

Expression Language 是为了使JSP写起来更加简单语法:${.....}内部能进行的运算:算术、关系、逻辑、三元、空值判断${empty xxx}

JSP九大内置对象

pageContext------->页面内容对象
request----------->请求对象
session----------->会话对象
application------->服务器对象response---------->响应对象
config------------>初始化数据对象
out--------------->输出对象
page-------------->当前页面对象,类似于Java中的this
exception--------->异常对象Servlet中PrintWriter与JSP中out的区别:PrintWriter,不带缓冲区,直接写到页面上out,有缓冲区,先到缓冲区,再到页面上

JSP四大作用域

Servlet中的作用域:request:是请求范围session:是会话范围ServletContext:是应用范围JSP中的作用域:pageContext:针对页面,在当前页面内有效。(是JSP独有的)request:请求范围session:会话范围application:应用范围如果四大作用域中存入了相同key的数据?按照pageContext-->request-->session-->application的顺序寻找,找到了就结束使用EL表达式,获取指定作用域的数据:pageContext-->pageScoperequest-->requestScopesession-->sessionScopeapplication-->applicationScope

JSP动作标签

一共13个需要了解的:jsp:forward,include,其他的:jsp:attribute,body,element,fallback,getProperty,output,param,params,plugin,setProperty,useBeanjsp:forward:跳转到某个页面<jsp:forward page="跳转页面"></jsp:forward>
jsp:include:将某个页面包含到本页面<jsp:include page="xxx.jsp"></jsp:include>注意:此标签在包含时,先将所有的JSP文件翻译成java文件,再组合到一起。include指令(静态包含)与include标签(动态包含)的区别:1、语法不一样2、翻译方式不一样,指令只翻译一个文件,标签翻译所有文件3、指令的效率相对较高,标签较低4、指令不能携带数据,标签可以

JSTL标签库

Java server pages standarded tag library (jsp标准标签库)步骤:导jar包->在jsp页面使用taglib指令来导入需要的标签库核心:xxxx/jstl/core引入:<%@ taglib uri="xxx/jstl/core" prefix="c" %>使用:创建变量:<c:set var="name" value="xxx"></c:set>输出:<c:out value="${name}"></c:out>移除变量:<c:remove var="name"></c:remove>如果:<c:if test="${3>2}">输出内容</c:if>选择:<c:choose><c:when test="xxx">输出的内容</c:when><c:otherwise><c:when test="xxx">输出的内容</c:when><c:otherwise></c:otherwise></c:choose>循环(注意items双引号里面不要加空格):<c:foreach var="u" items="${list}">账号:${u.uname},密码:${u.pad}</c:foreach>格式化:xxxx/jstl/fmt函数:xxxx/jstl/functions引入:<%@ taglib uri="xxx/jstl/functions" prefix="fn" %>使用:字符串长度:${fn: length(str)}                .......

Ajax

Asynohronous JavaScirpt And Xml ------ 异步的JavaScript和XML它不是一种技术,是多种技术联合实现的产物。Ajax是浏览器客户端上的前端技术异步和同步有什么区别?A线程和B线程,并发执行,谁也不等谁,这就是异步A线程和B线程,在其中一个线程执行的时候另外一个线程需要等待,这就是同步;传统的请求和Ajax请求有什么区别?传统的请求都是同步的,Ajax可以做到异步请求。Ajax经典案例:Goole的auto_complete 、 Goole的map浏览器本身是支持多线程并发的,其中ajax请求就是一个线程。一个页面上可以同时发送多个ajax请求,多个ajax对应浏览器对个线程。 Ajax实现四步:1、创建Ajax核心对象XMLHttpRequest//浏览器内置的,可以直接使用。var xhr;if(window.XMLHttpRequest()){xhr = new XMLHttpRequest();} else{xhr = new ActiveXObject("Microsoft.XMLHTTP");//ie5和ie6只支持这种对象}2、注册回调函数/*当xhr对象的readyState属性发生改变的时候,回调函数就会执行XMLHttpRequest对象在请求和响应的过程中,该对象的属性readyState状态从0-4:0:请求未初始化   1:服务器连接已建立       2:讲求已接收3:请求处理中         4:请求已完成,且响应已就绪*/xhr.onreadystatechange = function(){if(xhr.readyState == 4){if(xhr.status == 200){//xhr.status属性可以获取到HTTP啥响应状态码。//在浏览器端使用xhr对象接收服务器端响应回来的文本var s = xhr.responseText;//responseText是属性.....}else{alert(xhr.status)}}}3、开启浏览器和服务器之间的通道//这里只是开启通道xhr.open(method,url,asyn);//asyn-true表示支持异步,asyn-false表示支持同步//如果是用的get请求,则在url后面添加要提交的数据 //如果是用post,则必须使用表单提交数据,以下代码行必须加上(可以从表单的enctype属性里面找)//Ajax post请求的乱码,需要在这里处理,注意字符集需要和浏览器及服务器字符集相同//xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");4、发送Ajax请求xhr.send();//post请求提交数据在send里面提交eg:send(username=aaa&pwd=bbb)注意:如果Ajax发送请求的方式是get,那么为了防止第n+1次访问走缓存,可以使用“加时间缀”的方式避免。var timeStamp = new Date().getTime();在路径后面加的时候可以使用下划线加:?_=timeStamp&.....jQuery版AJAX
jQuery封装的AJAX常用的三种方法:
一、$.ajax({url:"",type:"get/post",data:{"key":"value","key":"value",...},dataType:"响应的数据类型",success:function(){},error:function(){}}); //参数顺序可变二、$.get("url",{"key":"value","key":"value",...},function(){.......},dataType);//注意参数顺序不可变,函数是成功的回调函数三、$.post("url","key":"value","key":"value",...,function(){...........},dataType);
返回数据的格式:text,json,html,script,jsonp,xml表单序列化:作用:可以获取表单中用户输入的请求。关键字:serializeeg:var data = $("#form").serialize();
工具类
DBUtil:
public  class DBUTils{private DBUTils() {}static ComboPooledDataSource ds = new ComboPooledDataSource();static QueryRunner qr = new QueryRunner(ds);public static QueryRunner getQueryRunner() {return qr;}
}DateUtils:
public class DateUtils {private DateUtils() {}public static Date stringToDate(String time) {Date date = null;SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");try {date = sdf.parse(time);} catch (ParseException e) {e.printStackTrace();}return date;}public static String dateToString(Date date) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");return sdf.format(date);}
}PageUtil:
public class PageUtil {private int currPage;//当前页private int rows; //每页显示多少private int index;//偏移量private int countRows;//总记录数private int countPages;//总页数private int prevPage;//前一页private int nextPage;//后一页public PageUtil(String currPage,int rows,int countRows) {//只提供一个构造方法,用来生成对应的页码this.rows = rows;this.countRows = countRows;currPage(currPage);index();countPages();prevPage();nextPage();}//根据提供的参数初始化所有数据private void currPage(String currPage) {if (currPage == null || "".equals(currPage)) {this.currPage = 1;}else {this.currPage = Integer.parseInt(currPage);}}private void index() {index = (currPage-1)*rows;}private void countPages() {countPages = (countRows+rows-1)/rows;}private void prevPage() {if (currPage != 1) {prevPage = currPage-1;}else {prevPage = 1;}}private void nextPage() {if (currPage != countPages) {nextPage = currPage +1;}else {nextPage = countPages;}}生成所有属性的get方法,因为只需要别人调用,不需要别人设置!
}
BaseServlet
public class BaseServlet extends HttpServlet {protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置字符编码集request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");String flag = request.getParameter("flag");//获取类型Class theClass = this.getClass();//获取字节码对象// 根据flag通过反射机制获取方法try {Method md = theClass.getDeclaredMethod(flag, HttpServletRequest.class,HttpServletResponse.class);md.setAccessible(true);// 打破修饰符md.invoke(this, request,response);// 调用方法} catch (Exception e) {e.printStackTrace();}}}

Tomcat_Servlet相关推荐

  1. javaweb_笔记1(系统架构;servlet分析,注册,生命周期;Servletconfig对象(四个方法)和Servletcontext对象;http协议,get,post)

    1.关于系统架构 1.1系统架构包括 C/S架构: Client/Server(客户端/服务器) 例如电脑上安装的各种软件,qq等,需要安装特定的软件 优点: 速度快(软件中数据大部分在客户端中,少量 ...

最新文章

  1. Java访问权限(详尽版)
  2. 鱼佬阿水竞赛相声:我是如何2小时杀进排名前10%的!
  3. NGUI从入门到实战第1章开启NGUI学习之旅
  4. Java删除文件和目录
  5. SpringBoot中使用Redis数据库
  6. JAVA面试必备的知识宝典(一)
  7. jzoj2755-[2012东莞市选]树的计数【dp,高精度】
  8. css中px、em和rem的区别总结
  9. bootstrap java web_Java web MVC(jsp,servlet,dao)+Bootstrap购物网站开发经验总结 (持续更新)...
  10. 设置,获取和删除Cookies
  11. centos mysql开发包_CentOS 7 安装 MySQL-阿里云开发者社区
  12. Android Studio — Could not determine java version from ‘11.0.8‘. The project uses Gradle version wh
  13. oa系统服务器数据库,oa数据库和服务器
  14. Oralce 之 TM锁
  15. Tyvj P1864 守卫者的挑战
  16. (转载)李剑英的CSLight入门指南结合NGUI热更新
  17. CPU卡指令返回错误集
  18. 如何评价 APICloud ?
  19. Spring Boot整合Shiro + Springboot +vue
  20. Android手机APP广告植入与产品上线

热门文章

  1. 深度学习能辨识壁画上的艺术元素吗?
  2. 推特超2K赞,DeepMind强化学习综述:她可以很快,但快从慢中来
  3. 国字号遥感算法大赛!涵盖主流视觉任务,头奖10万人民币!
  4. CVPR 2019 | 旷视提出极轻量级年龄估计模型C3AE
  5. 基于OpenCV与Dlib的行人计数开源实现
  6. linux如何将文件夹添加到书签,桌面应用|[新手技巧] 如何在Ubuntu中添加和删除书签...
  7. 用Python把github上非常实用的数据全部抓取下来! 留给自己备用
  8. 深度学习行人重识别综述与展望
  9. 免费公开课 | 强化学习及其在竞速无人机中的应用
  10. 大数据预测实战-随机森林预测实战(一)-数据预处理