达内培训笔记——Servlet—图片验证码——文件上传——老师说什么抄什么

图像

图片放到 webroot 下的一个文件夹 image 里面

可以在浏览器直接输入 http://localhost:8080/servlet/image/1.jpg 即可显示图片

l      可以用标签 <img src=”” width=”  " height=” “ />

l      建一个能生成图片的 servlet ,让它继承一个叫 HttpServlet 类,为什么该继承呢? HttpServlet 已经实现了 Servlet 接口,因为这个类用起来方便,

l      适配器模式:有一个接口,里面有许多方法;要求某一个类必须实现这个接口,大多情况下这个类会写一部分方法,其他方法什么也不干,保留在类中;再建另一个类继承上一个类,这个类随便实现父类的方法与否。

l      servlet 类中有 doGet doPost 方法;或者通过 service 方法,它会根据判断请求方式,可以处理两种请求, HttpServletReques ServletRequest 接口的子接口,这样看来 ServletRequest 用处不大,这叫过度设计,会导致系统很复杂,

画图步骤

1, 在内存中生成位图(图片最原始格式的是 bmp 格式),如 windows 的画图程序,位图在计算机以二进制数据保存,有一个一个亮点组成 1024×768 ,表示横店 1024 个点,竖 768 28 表示一个点 3 个字节,每个是 8 位,每个字节表示一种颜色,红绿蓝(都为 0 255 ),一般在网上传都不用 bmp 格式因为它太大了,所以都用压缩格式: jpeg 格式。

2, 压缩成 JPEG

3, 输出

l        BufferdImage image = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB); 像素是 200×200 第三 , 个参数用理会,

Graphics g = image.getGraphics();// 封装了一些画笔操作

Random r = new Random();

g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)); 红色    //0~255

// g.drawString("Hello", 50, 50); 可以这样写文字

g.fillRect(0,0,200,200);    矩形 ,1 2 参数是左上表达坐标, 3 4 是长和宽

// 其实 response.getWriter ()和

response.setContentType(“image/jpeg”);// 告诉浏览器你送的不是文本而是图片格式

      OutputStream os = response. getOutputStream();

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);   (new FileOut…// 可放到文件中它是一边压缩一边把压缩的内容输出, BufferedImage 需要有一个输出流跟它管理。

l        在页面做个链接

l        <a href=”javascript:alert(‘hello’)”> 看不清 </a>

l        <a href=”” οnclick=”alert(“hello”)> 看不清 </a>// 这样执行 onclick 后还会执行廉洁,这样颜色发生改变

l        <a href=”javascript:;” οnclick=”alert(“hello”)>// 一般都喜欢这么写, 点这个之后就只是运行 onclick ,而不会进行连接,这样图片颜色也不改变,

<a href=”javascript: alert(‘hello’);” >// 也可这样写,但是有点小毛病,看 状态栏显示,显示 javascript: alert(‘hello’); 这样不是很好,程序员不希望被别人看到自己的隐私,其实也没什么,一般人都不看,

不可以直接这么写 <a href=” alert(‘hello’);” >

l        <a href=”javascript:;”οnclick=”document.getElem…(‘image1’).src=’../img1.jpg’” >// 浏览器只要发现 src 的值被改了就会重新访问 src 地址,浏览器只是刷新图片,而不是整个页面都刷新,修改的 src 跟以前必须不一样,所以 (‘image1’).src=’../image’ 是不行的,但是可以添加一个 get 请求方式,给一个参数就可以了, (‘image1’).src=’../image?12345’ 它仍然是访问那个 servlet tomcat 只把 ? 前边的当作地址, 可以让参数每次不一样,可以用 (‘image1’).src=’../image?’+(new Date()).getTime()” ,将 onclick 写到图片上就可以了。

l        添加 function changeImage(){

var imag = document.getElement..(“image1”);

imag.src = “image?new Date()”;

上传图片

在实际开始的时候不一定等需求都做好了才编码。

在传图片的时候不能用 Post 协议传, name=”…”&… 很难表示;

使用 commons-uploadfile.jar

l        先建一个叫 UploadFileServlet 生成页面 , 它接受的是 get 请求,因为没有东西要提交给它。

根目录叫 : uploadfile, 路径: uploadfile

servise 里:

       PrintRiter out = response.getWriter();

       out……

       out.println(“<form name=”desc” action=’uploadfile’  method=’post’enctype=’multipart/form-data’>”) ;// 编码的种类 , 一定要有,不写的话就用默认的设置,默认只能传文本(如 ?name=’lili’&age=’20’ ),如果传二进制文件就必须这样写。

       out.println(“<td> <input type=‘file’ name=‘file’/>);

l        再写一个 UploadActionServlet 用于开始上传,生成 doPost() 方法。

doPost(){

/*InputStream is = request.getInputStream();;// 获得浏览器上传的数据

Sys…(is.read());// 读一个字节看是什么,输出的是 45 ,这个输出并不是文件的开头那个字节,

Sys…(is.available);// 可以读到的流的字节数,为 0 ,这个方法是个不可靠的方法,用这个流比较费事 */

n        用下面:

DiskFileItemFactory dfif = new DiskF….();// 这个对象该对象可以用于控制性能方面的参数,比如指定缓存,上到 struts 再详细说,

ServletFileUpload upload = new ServletFileUpload(dfif);// 这个重要,它封装了上传数据的解析过程(获取方法),真正用于获取文件信息的是 upload

upload.setSizeMax(1024*1024);// 上传文件大小,这个必须要设置 ,否则黑客很容易捣乱,它只要传个超大的文件,那么你的系统就垮了

List<?> list = upload.parseRequest(request);// upload 去解析

/*Sys…(list);// 打印出来看看,

for(int I = 0;i<list.size();i++){

FileItem item = (FileItem)list.get(i);

//list 里面放的是 FileItem 对象,一个 list 表示一个文件,如果要传好几个文件,那么一个 FileItem 用来封装一个上传文件的信息。可以通过 FileItem 来获取文件的信息,通过输入流获取文件的内容,只要借一个输出文件流从输入流拷贝内容出来

// 打印出了 commons.fileupload.disk.DiskFileItem

*/

FileItem fileItem = (FileItem)list.get(0);

Sys…(fileItem.getName());//happy.JPG 就是文件名称 , 如果是非文件的话 ( 普通文本框 ), 返回 null

Sys…(FileItem.isFormFiled());// 如果是 false 表示为文件,是 true 则是通常的一个表单

request.getParameter(“desc”);// 不能用来获取文件,只能获取参数,返回值是空的。

 

Sys…(FileItem.getFileName()); // 获得对应表单的 name

Sys…(FileItem.getString());// 可以是文本框的值,

Sys…(fileItem.getSize());// 文件的大小

Sys…(FileItem.getInputStream());// 你上传的那个文件用到文件流

FileOutputStream os = new F…(fileItem.getName);

InoutStream is = fileItem.getInputStream();

IOUtils.copy(is,os);// 从输入流拷贝到输出流,这样不用写 for 循环

is.close();

os.close();

默认传到 tomcat/bin 下面,可是图片坏了,显示不出来,那是因为流没有关闭。

                                                                       

运行:

报错: NoClassDefFoundError/…, 你这个系统用到某个开源组件,这个组件你虽然导进去了,但是这个组件又需要其他的开源包,你少了这个,就报这个错,如少了 common-io.1.4.jar 包没有导入。导入就 OK

l        ServletFileUpload fileUpload = …

List<FileItem> list = fileUpload.parseRequest(request);

FileItem item = (FileItem);ist.get(0);

item.getName();

item.getSize();

item.getInputStream();

l        做一个文件上传,然后把文件内容打印到控制台

DiskFileItemFactory dfif = new DiskF….();

ServletFileUpload upload = new ServletFileUpload(dfif); upload.setSizeMax(1024*1024);

List<?> list = upload.parseRequest(request);// list 放到都是 fileItem, List 不够好,用 Map 比较好。

如果做排序或做插入用 List 集合,如果找其中的身份证号是谁,就用 map ,往往 key value 的一部分, map.put(person.getName(),person); 找到时候: Person p =(Person)map.get(“java”); 针对什么查找就什么做键,另外的做值,

Map<String,FileItem> map = HashMap<String,FileItem>;

for(int I = 0;i<list.size();i++){

FileItem item = (FileItem)list.get(i);

map.put(item.getFieldName(),item);

}

这样就很方便:

FileItem file = map.get(“file”);

map.get(“desc”);

map.get(“file”);// 这是个通常的编程技巧,这样可以方便的交互访问

Sys…(map.get(“desc”).getString());

FileItem file = map.get(“file”);// 返回的是 fileItm

我想存到服务器端,我不想用他原来的名字,它的名字可能乱七八糟,我们用当前系统的毫秒数做文件名 , 一般服务器不会使用你提交的文件名

String name = file.getName();

file.getName().subString(name.lastIndexOf(“.”));// 包括了小点

String fileName=String.valueOf(“System.currentTimeMillis()+name);

File up = new File(fileName);

file.write(up);// 这个比上面还简单 , 文件不需要关,文件流才要关 , 用流也行,记得要关了。

l        一般不传到默认路径( tomcat/bin 下)

 

改为:

String dir=”upload”;

ServletContext ctx = getServletContext();// 这玩意有时候也会用

 

File up = new File(“upload”,fileName);

 

 

l        经典案例:点浏览——选文件——文件描述——提交。再写一个 Servlet 展示图片。

写两个 Servlet 一个负责上传,一个负责展示出来

数据库有一张表,存文件名

数据表里面不存图片,因为将来拿出来的时候效率很低,图片不涉及到查找问题,所以放名字进去就可以,现在还不能说把一个人的图片放进去找个一模一样的照片出来,不过以后可能会这样搜索

n        上传要做两件事:上传,写入数据库

n        显示图片也要做两件事:读数据库信息,生成一个 HTML 通过 for 循环输出 <img src…./> 显示图片, upload/…

n        通过重定向,点击确定上传的时候就直接显示图片,数据库的访问都用 DAO 封装

Servlet 生命周期

1,  客户端发送请求—— > 容器

2,  容器解析请求

3,  容器创建 Servlet 实例

4,  容器调用 init ()方法

5,  容器调用 service ()方法

6,  容器输出相应

7,  容器返回响应—— > 客户端

8,  容器调用 destroy 方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值