. 增强HttpServletResponse对象
1. 实现一个增强的HttpServletResponse类,需要继承javax.servlet.http.HttpServletRequestWrapper类,通过重写自己需要增强的方法来实现(这种模式就叫做装饰者模式),使用该增强类在加上过滤器就可以实现无编码转换处理代码。
public class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest req; public MyRequest(HttpServletRequest request) { super(request); req=request; } @Override public String getParameter(String name) { //解决编码问题,无论是post还是get请求,都不需要在业务代码中对编码再处理 String method=req.getMethod(); if("get".equalsIgnoreCase(method)){ try { String str=req.getParameter(name); byte[] b=str.getBytes("iso8859-1"); String newStr=new String(b, "utf-8"); return newStr; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else if("post".equalsIgnoreCase(method)){ try { req.setCharacterEncoding("utf-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //绝对不能删除此行代码,因为此行代码返回的就是编码之后的数据 return super.getParameter(name); } }
在过滤器中应用
public class FilterTest4 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //生成增强的HttpServletRequest对象 HttpServletRequest req=(HttpServletRequest) request; MyRequest myReq=new MyRequest(req); //将增强的HttpServletRequest对象传入过滤器执行链中,在后面传入的request对象都会是增强的HttpServletRequest对象 chain.doFilter(myReq, response); } @Override public void destroy() {} }
2. 文件上传原理过程
1. JavaWeb中实现文件上传:
<html> <head> <title>My JSP 'upload.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <form action="" method="post" enctype="multipart/form-data"> <input type="text" name="name"> 请选择文件:<input type="file" name="upload"> <input type="submit" value="上传"> </form> </body> </html>
import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; public class UploadServlet extends HttpServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /** * 1. 创建磁盘文件项工厂类 DiskFileItemFactory * 2. 创建核心解析Request类 ServletFileUpload * 3. 开始解析Request对象中的数据,并返回一个List集合 * 4. List中包含表单中提交的内容 * 5. 遍历集合,获取内容 */ DiskFileItemFactory fac=new DiskFileItemFactory(); ServletFileUpload upload=new ServletFileUpload(fac); upload.setHeaderEncoding("utf-8");//防止中文的文件名乱码 try { List<FileItem> fileItems = upload.parseRequest(req); for(FileItem item:fileItems){ //有可能是普通文本项,比如<input type="text">标签提交上来的字符串 //也有可能是<input type="submit" value="上传">上传的文件 //文件项与普通项有不同的API来处理 //首先判断是普通文本项还是文件项, if(item.isFormField()){ //true表示普通文本项 //获取文本项的name属性值 String name=item.getFieldName(); //获取对应的文本 String value=item.getString("utf-8");//防止中文乱码 System.out.println(name+":"+value); }else{ //false表示文件项 //先获取文件名称 String name=item.getName(); //获取文件项的输入流 InputStream in=item.getInputStream(); //获取服务器端文件存储的目标磁盘路径 String path=getServletContext().getRealPath("/upload"); System.out.println(path); //获取输出流,输出到本地文件中 OutputStream out=new FileOutputStream(path+"/"+name); //写入数据 int len=0; byte[] b=new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); } in.close(); out.close(); } } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
注意:在文件上传时,会将form表单的属性enctype属性值为"multipart/form-data",当提交到服务端后,无法使用 req.getParameter(name) 方法来获取到内容,只有通过上面的方法来获取文本项。
2. 文件上传相关核心类:
//改进上面的文件上传代码,添加一个临时文件 public class UploadServlet extends HttpServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { DiskFileItemFactory fac=new DiskFileItemFactory(); fac.setSizeThreshold(1024*1024);//设置缓冲区为1mb //设置临时文件的本地磁盘存储路径 File repository=new File(getServletContext().getRealPath("/temp")); fac.setRepository(repository); ServletFileUpload upload=new ServletFileUpload(fac); upload.setHeaderEncoding("utf-8");//防止中文的文件名乱码 try { List<FileItem> fileItems = upload.parseRequest(req); for(FileItem item:fileItems){ if(item.isFormField()){ String name=item.getFieldName(); String value=item.getString(); String value=item.getString("utf-8");//防止中文乱码 System.out.println(name+":"+value); }else{ String name=item.getName(); InputStream in=item.getInputStream(); String path=getServletContext().getRealPath("/upload"); System.out.println(path); OutputStream out=new FileOutputStream(path+"/"+name); int len=0; byte[] b=new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); } in.close(); out.close(); } } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
3. 实现多文件上传(需要js技术):主要是更改jsp页面,通过js代码来添加多个文件进行上传,服务器代码无需更改
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'upload.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <script type="text/javascript"> function run(){ var div=document.getElementById("divId"); div.innerHTML+= "<div><input type='file' name='upload'><input type='button' value='删除' onclick='del(this)'></div>" } function del(presentNode){ var div=document.getElementById("divId"); div.removeChild(presentNode.parentNode); } </script> <div> 多文件上传<br/> <form action="/Servlet/upload" method="post" enctype="multipart/form-data"> <input type="button" value="添加" onclick="run()"><br/> <div id="divId"> </div> <input type="submit" value="上传"> </form> </div> </body> </html>
4. 关于文件上传的一些问题:
3. 文件下载
1. 传统文件下载方式有超链接下载或者后台程序下载两种方式。通过超链接下载时,如果浏览器可以解析,那么就会直接打开,如果不能解析,就会弹出下载框;而后台程序下载就必须通过两个响应头和一个文件的输入流。
2. 后台程序下载:
单的 ASP.NET 页面看上去就像普通的 HTML 页面。
Hello RUNOOB.COM
在开始学习 ASP.NET 之前,我们先来构建一个简单的 HTML 页面,该页面将在浏览器中显示 "Hello RUNOOB.COM":
Hello RUNOOB.COM! |
用 HTML 编写的 Hello RUNOOB.COM
下面的代码将以 HTML 页面的形式显示实例:
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
</center>
</body>
</html>
如果您想亲自尝试一下,请保存上面的代码到一个名为 "firstpage.htm" 的文件中,并创建一个到该文件的链接:firstpage.htm。
用 ASP.NET 编写的 Hello RUNOOB.COM
转换 HTML 页面为 ASP.NET 页面最简单的方法是,直接复制一个 HTML 文件,并把新文件的扩展名改成 .aspx 。
下面的代码将以 ASP.NET 页面的形式显示实例:
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
</center>
</body>
</html>
如果您想亲自尝试一下,请保存上面的代码到一个名为 "firstpage.aspx" 的文件中,并创建一个到该文件的链接:firstpage.aspx。
它是如何工作的?
从根本上讲,ASP.NET 页面与 HTML 是完全相同的。
HTML 页面的扩展名是 .htm。如果浏览器向服务器请求一个 HTML 页面,服务器可以不进行任何修改,就直接发送页面给浏览器。
ASP.NET 页面的扩展名是 .aspx。如果浏览器向服务器请求个 ASP.NET 页面,服务器在将结果发回给浏览器之前,需要先处理页面中的可执行代码。
上面的 ASP.NET 页面不包含任何可执行的代码,所以没有执行任何东西。在下面的实例中,我们将添加一些可执行的代码到页面中,以便演示静态 HTML 页面和动态 ASP 页面的不同之处。
经典 ASP
Active Server Pages (ASP) 已经流行很多年了。通过 ASP,可以在 HTML 页面中放置可执行代码。
之前的 ASP 版本(在 ASP.NET 之前)通常被称为经典 ASP。
ASP.NET 不完全兼容经典 ASP,但是只需要经过少量的修改,大部分经典 ASP 页面就可以作为 ASP.NET 页面良好地运行。
如果您想学习更多关于经典 ASP 的知识,请访问我们的 ASP 教程。
用经典 ASP 编写的动态页面
为了演示 ASP 是如何显示包含动态内容的页面,我们将向上面的实例中添加一些可执行的代码(红色字体标识):
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
<p><%Response.Write(now())%></p>
</center>
</body>
</html>
<% --%> 标签内的代码是在服务器上执行的。
Response.Write 是用来向 HTML 输出流中写东西的 ASP 代码。
Now() 是一个返回服务器当前日期和时间的函数。
如果您想亲自尝试一下,请保存上面的代码到一个名为 "dynpage.asp" 的文件中,并创建一个到该文件的链接:dynpage.asp。
用 ASP .NET 编写的动态页面
下面的代码将以 ASP.NET 页面的形式显示实例:
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
<p><%Response.Write(now())%></p>
</center>
</body>
</html>
如果您想亲自尝试一下,请保存上面的代码到一个名为 "dynpage.aspx" 的文件中,并创建一个到该文件的链接:dynpage.aspx。
ASP.NET 对比经典 ASP
上面的实例无法演示 ASP.NET 与经典 ASP 之间任何的不同之处。
正如最后的两个实例中,您看不出 ASP 页面和 ASP.NET 页面两者之间的不同之处。
在下一章中,您将看到服务器控件是如何让 ASP.NET 比经典 ASP 更强大的。
)CSS 标准盒子模型(Box Model)
在网页中所有HTML元素可以看作盒子,在CSS中,"box model"术语是用来设计和布局时使用的;CSS盒模型本质上是一个盒子,封装周围的HTML元素包括:外边距(margin)边框(border)内边距(padding)实际内容(content)四个属性,所以布局时每个元素所占的总宽高是这4个属性的总和;比如宽度:总元素的宽度=宽度+左填充+右填充+左边框+右边框+左边距+右边距
1.1Margin(外边距)清除边框外的区域,外边距是透明的
1.2Border(边框)围绕在内边距和内容外的边框
1.3Padding(内边距)清除内容周围的区域,内边距是透明的
1.4Content(内容)盒子里填充的内容比如文本,图像等
标准盒子模型
宽度为100px的div
根据盒子模型得出该元素的总宽度为:100+(20+20)+(15+15)+(15+15)(由里至外)因此如果想在此div中放置一个宽度为100px的元素,此元素的总宽度必须小于等于100px
2)DIV+CSS布局
Div+CSS布局就是将网页内容用<div>分割为块,之后使用css设置每个块的大小,位置等
DIV+CSS布局最重要的是灵活运用float(浮动)属性,其值:1)left 2)right 3)both
clear属性作用是清除浮动,其值为:1)left 2)right 3)both
d2向右浮动 float:right
因为div是块级元素,如果都没有脱离文档流div就会按照从上到下的顺序放置
d2设置为右浮动其他两个div位置的变化:
1)d1没有脱离文档流会占据一行,所以d2只能浮动到d1下面的右面如上图所示
2)d2脱离文档流,d3自动填充到d2的位置
d1,d2全部设置为右浮动
1)当d1,d2都设置为右浮动时:因为css中d1在d2上面先设置,因此d1在右侧,如果d2在d1上面先设置样式,则d2在右侧,d1在左侧,自己测试不再截图
2)当d1,d2都设置为右浮动时:d3就会跑到上图中d2的位置
3)如果3个div都设置左或右浮动,当3个width加一起<=100%就会在第一行显示(d1,d2,d3)
<style type="text/css">
#d1 {
margin: 0px;
background-color: red;
padding: 0px;
width: 50%;
height: 100px;
float:right;
}
#d2 {
margin: 0px;
background-color: yellow;
padding: 0px;
width: 50%;
height: 100px;
float:right;
}
#d3 {
margin: 0px;
background-color: green;
padding: 0px;
width: 50%;
height: 100px;
}
</style>
d2清除左浮动,d3设置为右浮动
当d2清除了左浮动,d3设置为右浮动,就会如上图所示;如果d2清除的是右浮动,d2就会在d1上面,d3就会定位在d1下面的右面,自己测试不再截图
当d2清除了左浮动,如果想要d2紧挨着d1(与d1在一行上),可以通过position脱离文档流设置其上下左右属性使其定位在d1右侧,自己测试
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>div+CSS布局</title>
<style type="text/css">
#d1 {
margin: 0px;
background-color: red;
padding: 0px;
width: 30%;
height: 100px;
float:left;
}
#d2 {
margin: 0px;
background-color: yellow;
padding: 0px;
width: 40%;
height: 100px;
clear: left;
}
#d3 {
margin: 0px;
background-color: green;
padding: 0px;
width: 30%;
height: 100px;
float: right;
}
</style>
</head>
<body>
<div id="d1"><span style="font-size: 50px;">d1</span></div>
<div id="d2"><span style="font-size: 50px;">d2</span></div>
<div id="d3"><span style="font-size: 50px;">d3</span></div>
</body>
</html>
DIV+CSS布局综合运用position+上下左右属性与float属性为网页进行布局
注意:浏览器的兼容性问题,特别是使用IE内核的浏览器对W3C的规范不怎么遵守
*请认真填写需求信息,我们会在24小时内与您取得联系。