一、servlet
1、什么是servlet
在Java web程序中,Servlet负责接收客户端的请求HTTPServletRequest(),并通过doGet()和doPost()方法处理并通过HTTPServletResponse()反馈给用户,实现动态页面。一个Servlet类只有一个实例,通过调用init()方法初始化,destroy()方法销毁,Servlet是非线程安全的。
2、servlet与tomcat
Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户。.而Servlet是一种运行在支持Java语言的服务器上的组件。
①Tomcat将http请求文本接收并解析,然后封装成HttpServletRequest类型的request对象,所有的HTTP头数据读可以通过request对象调用对应的方法查询到。
②Tomcat同时会要响应的信息封装为HttpServletResponse类型的response对象,通过设置response属性就可以控制要输出到浏览器的内容,然后将response交给tomcat,tomcat就会将其变成响应文本的格式发送给浏览器。
Java Servlet API 是Servlet容器(tomcat)和servlet之间的接口,它定义了serlvet的各种方法,还定义了Servlet容器传送给Servlet的对象类,其中最重要的就是ServletRequest和ServletResponse。所以说我们在编写servlet时,需要实现Servlet接口,按照其规范进行操作。
3、Servlet的生命周期
①servlet中的方法
void init(ServletConfig config)
void service(ServletRequset res,ServletResponse res)
void destroy()
String getServletInfo()
ServletConfig getServletConfig()
②生命周期
1)加载和实例化
当Servlet容器启动或客户端发送一个请求时,Servlet容器会查找内存中是否存在该Servlet实例,若存在,则直接读取该实例响应请求;如果不存在,就创建一个Servlet实例。
(2) 初始化
实例化后,Servlet容器将调用Servlet的init()方法进行初始化(一些准备工作或资源预加载工作)。
(3)服务
初始化后,Servlet处于能响应请求的就绪状态。当接收到客户端请求时,调用service()的方法处理客户端请求,HttpServlet的service()方法会根据不同的请求 转调不同的doXxx()方法。
(4)销毁
当Servlet容器关闭时,Servlet实例也随时销毁。其间,Servlet容器会调用Servlet 的destroy()方法去判断该Servlet是否应当被释放(或回收资源)。
4、Http的get请求和post请求
①get请求用来从服务器上获得资源,post向服务器提交数据。
②get请求将表单中数据按照name=value形式添加到action所指向的url后面;post请求将表单中的数据放在HTTP协议的请求头或消息体中,传递到action所指url。由于url长度有限,所以不用get请求上传数据,一般用来搜索查询。
5、转发和重定向
转发是服务器行为,重定向是客户端行为
转发通过RequestDispatcher(请求的派发者)的forward(HttpServletRequest request,HttpServletResponse response)方法实现,RequestDispatcher对象可以通过HttpServletRequset的getRequestDispatcher("你要跳转的页面")方法获得。
重定向是利用服务器返回的状态码实现的。客户端请求服务端的时候,服务器会返回一个状态码,服务器通过HttpServletResponse的setStatus(int Status)方法设置状态码。
①从地址栏来说
forward是服务器请求资源,再将资源转发给浏览器,浏览器不知道的来源,所以地址栏的URL不变
redirect是服务端根据逻辑,发送一个状态码,让客户端去请求那个资源,所以地址改变
②从数据共享来说
forward:转发页面和转发到的页面可以共享request里的数据
redirect:不能共享
③运用场景
forward一般用于用户登陆的时候,根据角色转发到相应的模块
redirect一般用于用户注销登陆时返回主页和跳转到其他网站等
④效率
forward高
redirect低(重定向客户端要请求两次)
6、Servlet的线程安全问题
Servlet不是线程安全的。
要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。
当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。
Thread1和Thread2调用了同一个Servlet,此时如果Servlet中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。
解决方法是在servlet中不要定义变量,尽量在doGet()和doPost()中定义局部变量。
二、JSP
1、jsp和servlet
①联系
Servlet是特殊的Java程序,运行于服务器的jvm中,向浏览器提供显示内容。
jsp是servlet的一种简易形式,jsp会被服务器处理成类似servlet的java程序。
②区别
Servlet的应用逻辑在java文件中,完全从表现层分离出来,偏重逻辑
jsp是Java和HTML组合成一个扩展名为.jsp的文件,偏重显示
2、JSP工作原理
①当用户访问一个JSP页面时,会向一个Servlet容器(Tomcat等)发出请求;
②如果页面有所改动,则servlet容器首先要把JSP页面(假设为test.jsp)转化为Servlet代码(test.java),再将其转化为class文件(test.class文件);这种过程(编译)会耗费时间
③JSP容器负责调用从JSP转换来的servlet,这些servlet负责提供服务相应用户请求;如果用户有多个请求,则容器会建立多个线程处理多个请求;
④容器执行字节码文件(包括调用的servlet:formprocessor.java字节码),并将其结果返回到客户端;(返回的最终方式是有servlet输出html格式的文件流)
3、生命周期
和Servlet类似;
4、内置对象
request:请求对象,是HttpServletRequest的实例
response:访问对象,是HttpServletResponse的实例
pageContext:页面上下文对象,可以访问当前页面的所有其他对象,和本类名同名
session:会话对象,是HttpSession类的实例
application:应用程序对象,可存放全局变量,实现用户间的数据共享,是ServletContext的实例
out:输出对象,是JspWriter的实例
config:配置对象,当一个servlet初始化时,容器把某些信息通过config对象传递给servlet,取得服务器的配置信息
page:页面对象,类似于指针,是Object的实例
exception:例外对象,表示异常,是Throwable的对象
page和pageContext的区别
pageContext和page都是jsp中的隐含对象,pageContext代表jsp页面的上下文关系,能够调用、存取其他隐含对象;page代表处理当前请求的时候,这个页面的实现类的实例。
5、request对象的方法
setAttribute(String name,Object):设置名字为name的request 的参数值
getAttribute(String name):返回由name指定的属性值
getAttributeNames():返回request 对象所有属性的名字集合,结果是一个枚举的实例
getCookies():返回客户端的所有 Cookie 对象,结果是一个Cookie 数组
getCharacterEncoding() :返回请求中的字符编码方式 = getContentLength() :返回请求的Body的长度
getHeader(String name) :获得HTTP协议定义的文件头信息
getHeaders(String name) :返回指定名字的request Header 的所有值,结果是一个枚举的实例
getHeaderNames() :返回所有request Header 的名字,结果是一个枚举的实例
getInputStream() :返回请求的输入流,用于获得请求中的数据
getMethod() :获得客户端向服务器端传送数据的方法
getParameter(String name) :获得客户端传送给服务器端的有 name指定的参数值
getParameterNames() :获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
getParameterValues(String name):获得有name指定的参数的所有值
getProtocol():获取客户端向服务器端传送数据所依据的协议名称
getQueryString() :获得查询字符串
getRequestURI() :获取发出请求字符串的客户端地址
getRemoteAddr():获取客户端的 IP 地址
getRemoteHost() :获取客户端的名字
getSession([Boolean create]) :返回和请求相关 Session
getServerName() :获取服务器的名字
getServletPath():获取客户端所请求的脚本文件的路径
getServerPort():获取服务器的端口号
removeAttribute(String name):删除请求中的一个属性
三、attribute和parameter
getParameter得到的都是String类型的。或者是用于读取提交的表单中的值(http://a.jsp?id=123中的123),或者是某个表单提交过去的数据;
getAttribute则可以是对象Object,需进行转换,可用setAttribute设置成任意对象,使用很灵活,可随时用;
getAttribute()是获取对象容器中的数据值;
request.getSession().setAttribute() 是给SESSION赋值;
request.getSession().getAttribute() 是获取SESSION的值;
request.getSession().removeAttribute() 是移出SESSION的值;
getParameter()是获取POST/GET传递的参数值;
getParameter:用于客户端重定向时,即点击了链接或提交按扭时传值用,即用于在用表单或url重定向传值时接收数据用。
getAttribute:用于服务器端重定向时,即在sevlet中使用了forward函数,或struts中使用了mapping.findForward。getAttribute只能收到程序用setAttribute传过来的值。
setAttribute 是应用服务器把这个对象放在该页面所对应的一块内存中去,当你的页面服务器重定向到另一个页面时,应用服务器会把这块内存拷贝另一个页面所对应的内存中。这样getAttribute就能取得你所设下的值,当然这种方法可以传对象。session也一样,只是对象在内存中的生命周期不一样而已。
getParameter只是应用服务器在分析你送上来的request页面的文本时,取得你设在表单或url重定向时的值。