1.getServletConfig()
在servlet初始化时,容器传递进来一个ServletConfig对象并保存在servlet实例中,该对象允许访问两项内容:初始化参数和
ServletContext对象,前者通常由容器在文件中指定,
允许在运行时向sevrlet传递有关调度信息,比如说getServletConfig().getInitParameter("debug")后者为servlet提供有关容器的信息。
此方法可以让servlet在任何时候获得该对象及配置信息。
getServletContext()
一个servlet可以使用getServletContext()方法得到web应用的servletContext即而使用getServletContext的一些方法来获得一些值,比如说getServletContext().getRealPath("/")来获得系统绝对路径,getServletContext().getResource("WEB-INF/config.xml")来获得xml文件的内容。
getServletContext()取得的是 <context-param>配置的参数
getServletConfig()取得的是 <servlet> <init-param>配置的参数
2: getServletContext()应用于整个web App,而getServletConfig()仅应用于当前Servlet。 但是ServletConfig对象拥有ServletContext的引用。所以可以通过getServletConfig()来获得web App的初始值。
----------------------------------------------------------------------------------------------------------------------------------------------------------
pageContext对象
pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。
通过pageContext获得其他对象
getException方法返回exception隐式对象
getPage方法返回page隐式对象
getRequest方法返回request隐式对象
getResponse方法返回response隐式对象
getServletConfig方法返回config隐式对象
getServletContext方法返回application隐式对象
getSession方法返回session隐式对象
getOut方法返回out隐式对象
pageContext封装其它8大内置对象的意义,思考:如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将具有什么功能?
pageContext作为域对象
pageContext对象的方法
public void setAttribute(java.lang.String name,java.lang.Object value)
public java.lang.Object getAttribute(java.lang.String name)
public void removeAttribute(java.lang.String name)
pageContext对象中还封装了访问其它域的方法
public java.lang.Object getAttribute(java.lang.String name,int scope)
public void setAttribute(java.lang.String name, java.lang.Object value,int scope)
public void removeAttribute(java.lang.String name,int scope)
代表各个域的常量
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
findAttribute方法 (*重点,查找各个域中的属性)
引入和跳转到其他资源
PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法。
方法接收的资源如果以“/”开头, “/”代表当前web应用。
JSP标签
JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。
JSP常用标签
1、<jsp:include>标签
<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
语法:
<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />
page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
<jsp:include>与include指令的比较
<jsp:include>标签是动态引入, <jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。
而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。
不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。
2、<jsp:forward>标签
<jsp:forward>标签用于把请求转发给另外一个资源。
语法:
<jsp:forward page="relativeURL | <%=expression%>" />
page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。
3、<jsp:param>标签
当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。
语法1:
<jsp:include page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
语法2:
<jsp:forward page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。
映射JSP
<servlet>
<servlet-name>SimpleJspServlet</servlet-name>
<jsp-file>/jsp/simple.jsp</jsp-file>
<load-on-startup>1</load-on-startup >
</servlet>
……
<servlet-mapping>
<servlet-name>SimpleJspServlet</servlet-name>
<url-pattern>/xxx/yyy.html</url-pattern>
</servlet-mapping>
如何查找JSP页面中的错误
JSP页面中的JSP语法格式有问题,导致其不能被翻译成Servlet源文件,JSP引擎将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。
JSP页面中的JSP语法格式没有问题,但被翻译成的Servlet源文件中出现了Java语法问题,导致JSP页面翻译成的Servlet源文件不能通过编译,JSP引擎也将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。
JSP页面翻译成的Servlet程序在运行时出现异常,这与普通Java程序的运行时错误完全一样,Java虚拟机将提示错误发生在Servlet源文件中的位置(行和列)以及相关信息。
----------------------------------------------------------------------------------------------------------------------------------------------------------
1.page指当前页面。只在一个jsp页面里有效 。
2.request 指从http请求到服务器处理结束,返回响应的整个过程。在这个过程中使用forward方式跳转多个jsp。在这些页面里你都可以使用这个变量。
3.Session 有效范围当前会话,从浏览器打开到浏览器关闭这个过程。
4.application它的有效范围是整个应用。
作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用
page里的变量没法从index.jsp传递到test.jsp。只要页面跳转了,它们就不见了。
request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。
session和application里的变量一直在累加,开始还看不出区别,只要关闭浏览器,再次重启浏览器访问这页,session里的变量就重新计算了。
application里的变量一直在累加,除非你重启tomcat,否则它会一直变大。
而作用域规定的是变量的有效期限。
如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。
从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。
所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。
所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。
整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。
application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request, session都是完全隔离的,无论如何修改都不会影响其他人的数据。
pageContext对象的范围只适用于当前页面范围,即超过这个页面就不能够使用了。所以使用pageContext对象向其它页面传递参数是不可能的。
request对象的范围是指在一JSP网页发出请求到另一个JSP网页之间,随后这个属性就失效。
session的作用范围为一段用户持续和服务器所连接的时间,但与服务器断线后,这个属性就无效。比如断网或者关闭浏览器。
application的范围在服务器一开始执行服务,到服务器关闭为止。它的范围最大,生存周期最长。
----------------------------------------------------------------------------------------------------------------------------------------------------------
JSP运行原理和九大隐式对象
每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用。
由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。
JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。
JSP九大隐式对象
request、response、config、application、exception、Session、page、out、pageContext
out隐式对象
out隐式对象用于向客户端发送文本数据。
out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。
只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
设置page指令的buffer属性关闭了out对象的缓存功能
out对象的缓冲区已满
整个JSP页面结束
pageContext对象
pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。
通过jsp写文件下载代码
<%@page import="java.io.OutputStream"%><%@page import="java.io.FileInputStream"%><%@page import="java.io.InputStream"%><%@page import="java.io.File"%><%@page import="java.net.URLEncoder"%><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%
ServletContext context = this.getServletContext();
String path = application.getRealPath("./images/da.jpg");
//构造文件
File file = new File(path);
/*构造文件的输入流*/
InputStream is = new FileInputStream(file);
response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(file.getName(),"UTF-8"));
OutputStream os = response.getOutputStream();
byte buffer[] = new byte[1024];
int len=0;
while((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
}
os.flush();
os.close();
is.close();
%>
<%int c=1;%>
<%Object count = application.getAttribute("count");%>
<%if(count ==null)
{application.setAttribute("count",c);%>
<%}else{application.setAttribute
("count",(Integer)(count)+1);}
out.println(count);
%>
----------------------------------------------------------------------------------------------------------------------------------------------------------
总结出el表达式简单的集合输出方式
一、EL简介
1.语法结构
${expression}
2.[]与.运算符
EL 提供.和[]两种运算符来存取数据。
当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用 []。例如:
${user.My-Name}应当改为${user["My-Name"] }
如果要动态取值时,就可以用[]来做,而.无法做到动态取值。例如:
${sessionScope.user[data]}中data 是一个变量
3.变量
EL存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。
因为我们并没有指定哪一个范围的username,所以它会依序从Page、Request、Session、Application范围查找。
假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null。
属性范围在EL中的名称
Page PageScope
Request RequestScope
Session SessionScope
Application ApplicationScope
二、EL隐含对象
1.与范围有关的隐含对象
与范围有关的EL 隐含对象包含以下四个:pageScope、requestScope、sessionScope 和applicationScope;
它们基本上就和JSP的pageContext、request、session和application一样;
在EL中,这四个隐含对象只能用来取得范围属性值,即getAttribute(String name),却不能取得其他相关信息。
例如:我们要取得session中储存一个属性username的值,可以利用下列方法:
session.getAttribute("username") 取得username的值,
在EL中则使用下列方法
${sessionScope.username}
2.与输入有关的隐含对象
与输入有关的隐含对象有两个:param和paramValues,它们是EL中比较特别的隐含对象。
例如我们要取得用户的请求参数时,可以利用下列方法:
request.getParameter(String name)
request.getParameterValues(String name)
在EL中则可以使用param和paramValues两者来取得数据。
${param.name}
${paramValues.name}
3.其他隐含对象
cookie
JSTL并没有提供设定cookie的动作,
例:要取得cookie中有一个设定名称为userCountry的值,可以使用${cookie.userCountry}来取得它。
header和headerValues
header 储存用户浏览器和服务端用来沟通的数据
例:要取得用户浏览器的版本,可以使用${header["User-Agent"]}。
另外在鲜少机会下,有可能同一标头名称拥有不同的值,此时必须改为使用headerValues 来取得这些值。
initParam
initParam取得设定web站点的环境参数(Context)
例:一般的方法String userid = (String)application.getInitParameter("userid");
可以使用 ${initParam.userid}来取得名称为userid
pageContext
pageContext取得其他有关用户要求或页面的详细信息。
${pageContext.request.queryString} 取得请求的参数字符串
${pageContext.request.requestURL} 取得请求的URL,但不包括请求之参数字符串
${pageContext.request.contextPath} 服务的web application 的名称
${pageContext.request.method} 取得HTTP 的方法(GET、POST)
${pageContext.request.protocol} 取得使用的协议(HTTP/1.1、HTTP/1.0)
${pageContext.request.remoteUser} 取得用户名称
${pageContext.request.remoteAddr } 取得用户的IP 地址
${pageContext.session.new} 判断session 是否为新的
${pageContext.session.id} 取得session 的ID
${pageContext.servletContext.serverInfo} 取得主机端的服务信息
三、EL运算符
1.算术运算符有五个:+、-、*或$、/或div、%或mod
2.关系运算符有六个:==或eq、!=或ne、<或lt、>或gt、<=或le、>=或ge
3.逻辑运算符有三个:&&或and、||或or、!或not
4.其它运算符有三个:Empty运算符、条件运算符、()运算符
例:${empty param.name}、${A?B:C}、${A*(B+C)}
四、EL函数(functions)。
语法:ns:function( arg1, arg2, arg3 …. argN)
其中ns为前置名称(prefix),它必须和taglib 指令的前置名称一置
补充:
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
FOREACH:
<c:forEach items="${messages}"
var="item"
begin="0"
end="9"
step="1"
varStatus="var">
……
</c:forEach>
OUT:
<c:out value="${logininfo.username}"/>
c:out>将value 中的内容输出到当前位置,这里也就是把logininfo 对象的
username属性值输出到页面当前位置。
${……}是JSP2.0 中的Expression Language(EL)的语法。它定义了一个表达式,
其中的表达式可以是一个常量(如上),也可以是一个具体的表达语句(如forEach循环体中
的情况)。典型案例如下:
Ø ${logininfo.username}
这表明引用logininfo 对象的username 属性。我们可以通过“.”操作符引
用对象的属性,也可以用“[]”引用对象属性,如${logininfo[username]}
与${logininfo.username}达到了同样的效果。
“[]”引用方式的意义在于,如果属性名中出现了特殊字符,如“.”或者“-”,
此时就必须使用“[]”获取属性值以避免语法上的冲突(系统开发时应尽量避免
这一现象的出现)。
与之等同的JSP Script大致如下:
LoginInfo logininfo =
(LoginInfo)session.getAttribute(“logininfo”);
String username = logininfo.getUsername();
可以看到,EL大大节省了编码量。
这里引出的另外一个问题就是,EL 将从哪里找到logininfo 对象,对于
${logininfo.username}这样的表达式而言,首先会从当前页面中寻找之前是
否定义了变量logininfo,如果没有找到则依次到Request、Session、
Application 范围内寻找,直到找到为止。如果直到最后依然没有找到匹配的
变量,则返回null.
如果我们需要指定变量的寻找范围,可以在EL表达式中指定搜寻范围:
${pageScope.logininfo.username}
${requestScope.logininfo.username}
${sessionScope.logininfo.username}
${applicationScope.logininfo.username}
在Spring 中,所有逻辑处理单元返回的结果数据,都将作为Attribute 被放
置到HttpServletRequest 对象中返回(具体实现可参见Spring 源码中
org.springframework.web.servlet.view.InternalResourceView.
exposeModelAsRequestAttributes方法的实现代码),也就是说Spring
MVC 中,结果数据对象默认都是requestScope。因此,在Spring MVC 中,
以下寻址方法应慎用:
${sessionScope.logininfo.username}
${applicationScope.logininfo.username}
Ø ${1+2}
结果为表达式计算结果,即整数值3。
Ø ${i>1}
如果变量值i>1的话,将返回bool类型true。与上例比较,可以发现EL会自
动根据表达式计算结果返回不同的数据类型。
表达式的写法与java代码中的表达式编写方式大致相同。
IF / CHOOSE:
<c:if test="${var.index % 2 == 0}">
*
</c:if>
判定条件一般为一个EL表达式。
<c:if>并没有提供else子句,使用的时候可能有些不便,此时我们可以通过<c:choose>
tag来达到类似的目的:
<c:choose>
<c:when test="${var.index % 2 == 0}">
*
</c:when>
<c:otherwise>
!
</c:otherwise>
</c:choose>
类似Java 中的switch 语句,<c:choose>提供了复杂判定条件下的简化处理手法。其
中<c:when>子句类似case子句,可以出现多次。上面的代码,在奇数行时输出“*”号,
而偶数行时输出“!”。
再补充:
1 EL表达式用${}表示,可用在所有的HTML和JSP标签中 作用是代替JSP页面中复杂的JAVA代码.
2 EL表达式可操作常量 变量 和隐式对象. 最常用的 隐式对象有${param}和${paramValues}. ${param}表示返回请求参数中单个字符串的值. ${paramValues}表示返回请求参数的一组值.pageScope表示页面范围的变量.requestScope表示请求对象的变量.sessionScope表示会话范围内的变量.applicationScope表示应用范围的变量.
3 <%@ page isELIgnored="true"%> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.JSP2.0中默认的启用EL语言.
4 EL语言可显示 逻辑表达式如${true and false}结果是false 关系表达式如${5>6} 结果是false 算术表达式如 ${5+5} 结果是10
5 EL中的变量搜索范围是:page request session application 点运算符(.)和"[ ]"都是表示获取变量的值.区别是[ ]可以显示非词类的变量
----------------------------------------------------------------------------------------------------------------------------------------------------------
请求与重定向的区别
一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发。
一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源,称之为请求重定向
RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
----------------------------------------------------------------------------------------------------------------------------------------------------------
Session:服务器端技术。(Cookie:客户端技术)在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
Session和Cookie的主要区别在于:
Cookie是把用户的数据写给用户的浏览器。
Session技术把用户的数据写到用户独占的session中。
Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
IE禁用Cookie后的session处理
实验演示禁用Cookie后servlet共享数据导致的问题。
解决方案:URL重写
response.encodeRedirectURL(java.lang.String url)
用于对sendRedirect方法后的url地址进行重写。
response.encodeURL(java.lang.String url)
用于对表单action和超链接的url地址进行重写。
Session可用来完成简单的购物功能,用户登录,防止表单重复提交,一次性验证码。
部分代码:
//怎么获取创建Session
HttpSession session=request.getSession();
//存入数据
session.setAttribute("name", "wyd");
//从Session中获取name的值
HttpSession session=request.getSession();
String value=(String) session.getAttribute("name");
System.out.println("name"+value);
Cookie:客户端技术。(Session:服务器端技术)程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中得web资源时,就会带着各自的数据区。这样,web资源处理的就是用户各自的数据了.
Javax.servlet.http.Cookie类用于创建一个Cookie,response接口中也定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类的方法:
public Cookie(String name,String value)
setValue与getValue方法
setMaxAge与getMaxAge方法
setPath与getPath方法 /day06
setDomain与getDomain方法
getName方法
Cookie的应用:显示用户上次访问时间和浏览过的内容。
部分代码:
//创建Cookie
Cookie ck=new Cookie("lastTime",System.currentTimeMillis()+"");
//有效日期为0时 创建cookie到会话结束 删除cookie
ck.setMaxAge(0);//1小时
ck.setPath("/2011-10-24/servlet/CookieDemo");
//发送给你的响应
response.addCookie(ck);
//发送cookie信息
String value=makeCookieValue(request,id);
//产生一个cookie对象
Cookie cookie=new Cookie("goodsHistory",value);
cookie.setMaxAge(60*60);
cookie.setPath("/2011-10-24");
//响应
response.addCookie(cookie);
//声明返回值变量
String goodsHistory=null;
//第一步:获取cookie
Cookie cookies[]=request.getCookies();
for(int i=0;cookies!=null && i<cookies.length;i++){ if("goodsHistory".equals(cookies[i].getName())){
goodsHistory=cookies[i].getValue();
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
一、解决中文乱码问题,解决中文乱码问题有三种方法:
1)通过设置响应的头来处理的
response.setHeader("Content-Type","text/.html;charset=UTF-8");
2)通过字节设置响应的头来处理的
response.getOutputStream().write("中国".getBytes("UTF-8"));
3)使用html语言里面的<meta>标签来控制浏览器行为
response.getOutputStream().write("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">".getBytes());
二、文件下载
下面是文件下载的代码:
package cn.csdn.web.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Demo01Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*文件下载
* 首先知道下载的资源*/
ServletContext context = this.getServletContext();
String path =context.getRealPath("/WEB-INF/classes/res/aa.jpg");
/*构造文件*/
File file= new File(path);
/*构造文件的输入流*/
InputStream is = new FileInputStream(file);
/*写:输出流
* 文件下载*/
response.setHeader("content-disposition", "attachment;filename=");
OutputStream os = response.getOutputStream();
byte buffer[] = new byte[1024];
int len = 0;
while((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
}
os.close();
is.close();
}
}
如果下载的是中文文件,就把上面代码中的
String path =context.getRealPath("/WEB-INF/classes/res/aa.jpg")
aa.jpg改为汉字
把response.setHeader("content-disposition", "attachment;filename=");
加上URLEncoder.encode(file.getName(), "UTF-8")
如:response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(file.getName(), "UTF-8"));
----------------------------------------------------------------------------------------------------------------------------------------------------------
ServletContext应用
前提: 1----------Enumeration<E>e代表枚举值
(x|y|z)*代表
无序的、里面互斥、可单独
X-----0到多
y-----0到多
z-----0到多
应用一:实现Servlet的转发。
注意:forward与include的区别
1---forward方法调用后在响应中的没有提交的内容被自动消除。将请求转发给其他的Servlet后,由被调用的Servlet负责对请求做出响应,而原先Servlet的执行则终止。
2---include方法使原先的Servlet和转发到的Servlet都可以输出响应信息,即原先的Servlet还可以继续输出响应信息。
在测试的Servlet中实现转发的步骤如下:
要利用ServletContext对象实现转发获取对象
ServletContext context = this.getServletContext();
在request对象中存入name属性
request.setAttribute("name", wyd");
根据转发的地址获取 RequestDispatcher对象
RequestDispatcher rd = context.getRequestDispatcher("/index.jsp");
调用转发方法 以下采用任意方法即可
rd.forward(request, response);
rd.include(request, response);
应用二:多个ServletContext通过ServletContext对象实现数据共享。
1--- 在InitServletde 通过ServletContext方法中利用ServletContext对象存入需要共享的数据。
获取ServletContext对象
ServletContext context=this.getServletContext();
存入共享的数据
Context.setAttribute(“name”,”wyd”);
2--- 在其它的Servlet中利用ServletContext对象获取共享的数据
获取ServletContext对象
ServletContext context=this.getServletContext();
获取共享数据
String name=context.getAttribute(“name”);
System.out.println(“共享数据的值是:”+name);
应用三:实现Servlet的转发
注意:重定向与转发的区别
1---地址栏的区别:转发地址栏不变
2---处理请求资源的位置不同:sendRedirect()方法可以跨WEB应用程序和服务器重新定位资源来处理请求。forward()方法只能在应用程序内部转发。
3---传值不同: forward()方法能在转发的地址中获取存入的作用域的值。但是,重定向不能。
应用四:利用ServletContext对象读取资源文件。
(这不会写只好用老师的代码了。。。)
读取资源文件(properties文件(属性文件))的三种方式
配置的properties的内容如下:
url=jdbc\:mysql\://localhost\:3306/3g
user=root
password=root
获取实现的代码如下:
/*获取ServletContext对象*/
ServletContext context = this.getServletContext();
//第一种方式
URL url = context.getResource("WEB-INF/classes/db.properties");
InputStream is = url.openStream();
//第二种方式
/*读取db.properties文件*/
String path =context.getRealPath("WEB-INF/classes/db.properties");
/*根据文件的路径 构建文件对象*/
File file = new File(path);
/*根据file文件对象 创建输入流*/
InputStream is = new FileInputStream(file);
//第三种方式
InputStream is = context.getResourceAsStream("WEB-INF/classes/db.properties ");
//以三种方式任意一种可以
/*解析properties的文件*/
Properties prop = new Properties();
//从输入流中读取属性列表(键和元素对)。
prop.load(is);
Set<String> set = prop.stringPropertyNames();
//遍历set集合
Iterator<String> it = set.iterator();
while(it.hasNext()){
String key = it.next();
String value = prop.getProperty(key);
System.out.println(key+"-----"+value);
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
Servlet的细节、ServletConfig对象、ServletContext对象及ServletContext应用
细节一:1. 由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上。这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
2.<servlet>元素用于注册Servlet,它包含有两个主要的元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。
3.一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。
例如: <web-app>
<servlet>
<servlet-name>111 </servlet-name>
<servlet-class>111t</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>222</servlet-name>
<url-pattern>/1/1.html</url-pattern>
</servlet-mapping>
</web-app>
细节二:1.同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。
2.在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。
例如:1.<servlet-mapping>
<servlet-name>www </servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2. <servlet-mapping>
<servlet-name>www</servlet-name>
<url-pattern> /action/*</url-pattern>
</servlet-mapping>
细节三:对于如下的一些映射关系:
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 *.do
问题:
当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应
Servlet引擎将调用Servlet3。
当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
细节四:1.Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
2.针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。
3.在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
细节五:如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。
例如:
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据
细节六:1.如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。
2.凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
3.在<tomcat的安装目录>\conf\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet 设置为了缺省Servlet。
4.当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet。
细节七:线程安全
1. 当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。
2.如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。
3. SingleThreadModel接口中没有定义任何方法,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。
4.对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立的Servlet实例对象。
5.实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。
ServletConfig对象
1. 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
- 当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
- 阅读ServletConfig API,并举例说明该对象的作用:
a) 获得字符集编码
b) 获得数据库连接信息
c) 获得配置文件,查看struts案例的web.xml文件
ServletContext对象
- WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
- ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
- 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
- 查看ServletContext API文档,了解ServletContext对象的功能。
ServletContext应用
- 多个Servlet通过ServletContext对象实现数据共享。
- 获取WEB应用的初始化参数。
- 实现Servlet的转发。
- 利用ServletContext对象读取资源文件。
a) 得到文件路径
b) 读取资源文件的三种方式
c) .properties文件(属性文件)
一、 “java.sql.SQLException: Data truncated for column 'sex' at row 1”html信息输入界面获取问题,可能有两种,method方法拼写错误,或者sex不一致,另一种html错误没有写完整,例如缺少结束标签等!
*=0到多次
+=1到多次
?=0到多次
,代表有序
|代表互斥!
Enumeration<E>e代表枚举值
二、getServletContext() 和getServletConfig() 的不同
getServletConfig()
在servlet初始化时,容器传递进来一个ServletConfig对象并保存在servlet实例中,该对象允许访问两项内容:初始化参数和
ServletContext对象,前者通常由容器在文件中指定,
允许在运行时向sevrlet传递有关调度信息,比如说getServletConfig().getInitParameter("debug")后者为servlet提供有关容器的信息。
此方法可以让servlet在任何时候获得该对象及配置信息。
getServletContext()
一个servlet可以使用getServletContext()方法得到web应用的servletContext 。即而使用getServletContext的一些方法来获得一些值 。比如说getServletContext().getRealPath("/")来获得系统绝对路径。 getServletContext().getResource("WEB-INF/config.xml")来获得xml文件的内容。getServletContext()取得的是 <context-param>配置的参数 getServletConfig()取得的是
<servlet> <init-param>配置的参数
2: getServletContext()应用于整个web App,而getServletConfig()仅应用于当前Servlet。 但是ServletConfig对象拥有ServletContext的引用。所以可以通过getServletConfig()来获得web App的初始值。
----------------------------------------------------------------------------------------------------------------------------------------------------------
http协议: 请求响应举例
一个HTTP响应代表服务器向客户端回送的数据,包括:一个状态行、若干消息头、以及实体内容 。
状态行
格式: HTTP版本号 状态码 原因叙述<CRLF>(如:HTTP/1.1 200 OK)
状态码:用于表示服务器对请求的处理结果,它是一个三位的十进制数。
一些状态码的意义:
100~199表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程
200~299表示成功接收请求并已完成整个处理过程,常用200
300~399为完成请求,客户需进一步细化请求。例如,请求的资源已经移动一个新地址,常用302、307和304
400~499客户端的请求有错误,常用404
500~599服务器端出现错误,常用 500
响应头
Location:服务器通过这个头告诉浏览器去访问哪个页面,这个头通常配合302状态码使用
Content-Encoding: 服务器通过这个头告诉浏览器,回送的数据采用的压缩格式
Content-Length: 服务器通过这个头告诉浏览器,回送的数据的大小
Content-Type: 服务器通过这个头告诉浏览器,回送数据的类型
Last-Modified: 服务器通过这个头告诉浏览器,资源的最后修改时间
Refresh:服务器通过这个头告诉浏览器,定时刷新网页
Content-Disposition: attachment; filename=aaa.zip:服务器通过这个头告诉浏览器,以下载方式打开数据
ETag: W/"7777-1242234904000":缓存相关的头,为每一个资源配一个唯一的编号
HTTP请求头字段
Range头指示服务器只传输一部分Web资源,可以用来实现断点续传功能。
Range设置要传输的字节范围:
Range: bytes=1000-2000(传输范围从1000到2000字节)
Range: bytes=1000-(传输Web资源中第1000个字节以后的所有内容)
Range bytes=1000(传输最后1000个字节)
HTTP响应消息头字段
Accept-Ranges:说明Web服务器是否支持Range。若支持,返回bytes;若不支持,则返回none.
Content-Range:指定返回的Web资源的字节范围。
格式为:Content-Range:Range字段(如:Content-Range:1000-3000/5000
----------------------------------------------------------------------------------------------------------------------------------------------------------
动态web资源:页面中供人们浏览的数据是由程序产生,不同时间点访问web页面看到的内容各不相同。
jsp技术的特点:允许页面中嵌套java代码,为用户提供动态数据。
jsp与servlet的区别:
servlet做为web应用中得控制器组件来使用。
Jsp技术作为数据显示模板来使用。
Servlet负责响应请求产生数据,并把数据通过转发通过转发技术带给jsp.数据的显示交给jsp来做。
因为允许页面中嵌套java代码,为用户提供动态数据。并且web服务器在执行jsp时,web服务器会传递web开发相关的对象给jsp。Jsp通过这些对象,可以与浏览器进行交互,所以jsp当然也是一种动态的web资源的开发技术。
Jsp语法:
<%
Java代码
%>
Jsp声明:
可用于定义jsp页面转换成的servlet程序的静态代码块、成员变量和方法。
对个静态代码块、变量和函数可以定义在一个jsp声明中,也可以分别单独定义在对个jsp声明中。
Jsp注释:
注释的格式:<%-- 注释信息 --%> jsp页面翻译成Servlet程序时,忽略jsp页面中被注释的内容。
乘法口诀,水仙花数,正三角形案例。
<body>
<div>
<div>
<h1>乘法口诀</h1>
<hr color="red"/>
</div>
<div>
<%
for(int i=1 ;i<10;i++){
for(int j=1;j<=i;j++){
%>
<%=j%>*<%=i%>=<%=j*i%>
<%
}
%>
<br/>
<%
}
%>
<br/>
</div>
<div>
<h1>水仙花数</h1>
<hr color="red"/>
</div>
<div>
<%
for(int m=0;m<1000;m++){
%>
<% int a=m/100; %>
<% int b=(m-100*a)/10; %>
<% int c=m-100*a-10*b; %>
<%
if(a*a*a+b*b*b+c*c*c==m){
%>
<%=m %>是水仙花数<br/>
<% } %>
<% } %>
</div>
<div>
<h1>正三角</h1>
<hr color="red"/>
</div>
<div align="center">
<% for(int w=1;w<=9;w++){
for(int y=1;y<9-w;y++){ %>
<% } %>
<% for(int z=1;z<=2*w-1;z++){ %>
*
<% } %>
<br/>
<% } %>
</div>
</div>
</body>
----------------------------------------------------------------------------------------------------------------------------------------------------------
语法:
INSERT INTO 表名[(列名[,列名]...)]VALUES(值[,值]...);
注意事项:
插入值类型必须与对应列的数据类型一致
数据不能超出长度
插入值得为之必须与列名顺序一致
字符和日期数据要放在单引号中
插入空值使用null
如果不指定插入哪一列, 就是插入所有列
中文数据
由于默认码表是utf8, 而cmd.exe的码表是gbk, 在插入中文数据的时候会报错, 所以我们需要修改客户端码表
先查看系统变量: SHOWVARIABLES LIKE 'character%';
修改客户端码表: SETcharacter_set_client=gbk;
这样就解决了中文插入的问题, 但在查询数据的时候仍然显示为乱码, 这是因为mysql向cmd传输数据的时候使用的是utf8
修改输出数据的码表: SETcharacter_set_results=gbk
删除
语法
UPDATE 表名 SET 列名=值[,列名=值]...[WHERE条件语句];
注意事项
WHERE子句选择满足条件的行进行更新, 如果不写, 则更新所有行
语法
DELETE FROM 表名 [where 条件语句]
注意事项
如果不加where子句, 将删除表中所有记录
delete只能用作删除行, 不能删除某一列的值, 需要用update
在delete和update的时候需要注意表与表之间的关联关系
删除表中所有数据可以使用: TRANCATE 表名, 这种方式会删除旧表重新创建, 在数据较多的时候使用
备份恢复数据库
备份数据库
输入quit退出mysql, 在cmd.exe中输入:
mysqldump –u用户名 –p密码 数据库名 > 文件名
恢复数据库
进入mysql.exe之后, 使用数据库之后
source 文件名
主键约束 primary key
通常我们在设计表的时候需要给每一条记录一个独有的标识, 我们就用主键来约束这个标识.
primary key用来标识一个字段, 这个字段是非空且唯一的.
创建表时设置主键
create table test2(
id int primary key,
name varchar(20)
);
删除主键
alter table test2 dropprimary key;
在制定列上添加主键
alter table test2 changeid id int primary key;
alter table test2 addprimary key(id);
设置主键自动增长
create table test3(
id int primary key auto_increment,
name varchar(20)
);
删除自增长
alter table test3 changeid id int;
设置自增长
alter table test3 changeid id int auto_increment;
UUID主键
128位的2进制, 32位16进制加上4个-
java.util.UUID.randomUUID().toString()
----------------------------------------------------------------------------------------------------------------------------------------------------------
一、 http协议简介:
![](http://hi.csdn.net/attachment/201110/13/0_1318510011vOo4.gif)
![](http://hi.csdn.net/attachment/201110/13/0_1318510224m7Ki.gif)
![](http://hi.csdn.net/attachment/201110/13/0_1318510710AAHJ.gif)
----------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------
Javabean
javabean:它是一个遵循特定写法的java类。
Javabean的特点: 这个java类必须具有一个无参的构造函数。
属性必须私有化。
私有化的属性必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵守一定的命名规范。
Javabean的属性:1--JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性。每个属性通常都需要具有相应的setter、 getter方法,setter方法称为属性修改器,getter方法称为属性访问器。
2--属性修改器必须以小写的set前缀开始,后跟属性名,且属性名的第一个字母要改为大写,例如,name属性的修改器名称为setName,password属性的修改器名称为setPassword。
3--属性访问器通常以小写的get前缀开始,后跟属性名,且属性名的第一个字母也要改为大写,例如,name属性的访问器名称为getName,password属性的访问器名称为getPassword。
4--一个JavaBean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。
Javabean在jsp中得使用标签:
1--<jsp:useBean>标签:用于在jsp页面中查找或实例化一个javabean组件。它用于在指定的域范围内查找指定名称的JavaBean对象:
a.如果存在则直接返回该JavaBean对象的引用。
b.如果不存在则实例化一个新的javabean对象并将它以指定的名称存储到指定的域范围中。
常用语法:1<jsp:useBean id="beanName" class"/> ="package.class"
scope="page|request|session|application
2<jsp:useBean…>
Body
</jsp:useBean>
2--<jsp:setProperty>标签:用于在jsp页面中设置一个javabean组件的属性。
语 法:<jsp:setProperty name="beanName"
{
property="propertyName" value="{string | <%= expression %>}" |
property="propertyName" [ param="parameterName" ] |
property= "*"
}/>
3--<jsp:getProperty>标签:用于在jsp页面中获取一个javabean组件的属性。
语法:<jsp:getProperty name="beanInstanceName" property="PropertyName" />
----------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------
//写汉字
String base = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740";
//写4个字
Color c = Color.BLUE;
g.setColor(c);
Font font = new Font("宋体", Font.ITALIC, 20);
g.setFont(font);
StringBuffer sb = new StringBuffer();
//产生汉字
for(int i=0;i<4;i++){
int location = new Random().nextInt(base.length()-1);
char chr = base.charAt(location);
sb.append(chr+"");
}
checkCode=sb.toString();
Graphics2D gd = (Graphics2D) g;
gd.rotate(0.05);
//把汉字写到图片上
g.drawString(checkCode, 10, 20);
}
public static void outImage(OutputStream os) throws IOException{
//创建图片
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, IMAGETYPE);
//得到图型
Graphics g = image.getGraphics();
// 设置图片背景色
setBackground(g);
//向图片上写边框
setBorder(g);
//向图片上写干扰线
setRandomLine(g);
// 7、向图片上写数据
setFont(g);
// 8、把图片写给浏览器
ImageIO.write(image, "gif", os);
}
//清楚浏览器缓存
response.setIntHeader("expires", 0);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
//通知浏览器以图片的方式打开
response.setHeader("Content-Type", "image/jpeg");
----------------------------------------------------------------------------------------------------------------------------------------------------------