WEB17基础加强篇笔记.docx
- 文档编号:16410687
- 上传时间:2023-07-13
- 格式:DOCX
- 页数:21
- 大小:25.48KB
WEB17基础加强篇笔记.docx
《WEB17基础加强篇笔记.docx》由会员分享,可在线阅读,更多相关《WEB17基础加强篇笔记.docx(21页珍藏版)》请在冰点文库上搜索。
WEB17基础加强篇笔记
第17章WEB17-基础加强篇
今日任务
Ø使用自定义注解完成仿@Test的作用.
Ø使用Servlet3.0完成文件上传.
Ø使用动态代理解决网站的字符集编码
教学导航
教学目标
了解JDK中提供的三个注解
会自定义注解及注解的反射.
能够简单使用Servlet3.0
掌握动态代理技术
了解类加载器
教学方法
案例驱动法
1.1上次课内容回顾:
1.2案例一:
使用自定义注解完成@Test注解功能类似的效果:
(必须写)
1.2.1需求
使用Junit是单元测试的工具.在一个类中使用@Test对程序中的方法进行测试.
自定义一个注解@MyTest也将这个注解加在类的方法上.使这个方法得到执行.
1.2.2分析:
1.2.2.1技术分析:
Ø【注解】
程序中有注释和注解
*注释:
给开发人员看的.
*注解:
给计算机(程序)看的.告知计算机(程序)代码时如何执行了
注解使用:
学习框架支持注解开发.
Ø【JDK提供的注解】
@Override:
描述方法的重写.描述重写接口或者父类方法。
在源码阶段-编译阶段检查方法是否重写。
如果没有重写,报错
@SuppressWarnings:
压制警告.写代码的时候可以压制警告,测试代码时候要删除注解,让警告显示
all
@Deprecated:
标记过时.并不影响方法的正常使用
//如果你想通知一个程序员,某个方法过时了
publicvoid_run(){
}
//如果你想通知程序或者通知程序员,某个方法过时了
@Deprecated
publicvoidrun(){
}
Ø自定义注解:
注解本质:
就是一个接口。
特殊的接口
注解必须配合反射才可以执行
接口中的方法------注解中叫做属性,而且可以给属性赋值
注解的类型
1、可以是基本数据类型
2、可以是String
3、可以是Class类型的
4、可以是枚举类型enum
5、可以是注解类型
6、可以是以上类型的一维数组
【自定义注解案例】
@interfaceMyAnno1{
}
带有属性的注解:
@interfaceMyAnno2{
inta()default1;
Stringb();
//注解属性的类型:
基本数据类型,字符串类型String,Class,注解类型,枚举类型,以及以上类型的一维数组.
//Dated();
Classclazz();
MyAnno3m3();//注解
Colorc();//枚举
String[]arrs();
}
@MyAnno4("aaa")//如果属性名称为value那么使用的时候value可以省略(只出现这一个value的属性情况下).
publicclassAnnotationDemo3{
}
@interfaceMyAnno4{
Stringvalue();
inta()default1;
}
@Target(ElementType.METHOD)
Target规定了,注解应该作用在哪里?
一般作用在方法上
@Retention(RetentionPolicy.SOURCE)
元注解:
修饰注解的注解
1.2.2.2步骤分析:
定义一个测试类
publicclassAnnotationDemo3{
@MyTest
publicvoiddemo1(){
System.out.println("demo1执行了...");
}
@MyTest
publicvoiddemo2(){
System.out.println("demo2执行了...");
}
publicvoiddemo3(){
System.out.println("demo3执行了...");
}
}
定义核心运行类:
在核心运行类中有一个主函数:
获得测试类中的所有的方法.
获得每个方法,查看方法上是否有@MyTest注解.
如果有这个注解,让这个方法执行.
1.2.3代码实现:
通过元注解定义注解存在的阶段.
*元注解也是一个注解:
修饰注解的注解.
自定义一个注解:
核心运行类:
publicclassDemo2{
publicstaticvoidmain(String[]args)throwsIllegalAccessException,IllegalArgumentException,InvocationTargetException,InstantiationException{
//运行有注解修饰的方法
//反射
//1、获取当前的类的Class对象
Classclazz=Demo2.class;
Demo2d2=(Demo2)clazz.newInstance();
//2、获取所有的方法对象method
Method[]ms=clazz.getMethods();
//3、遍历判断判断方法上是否有注解修饰
for(Methodm:
ms){
//如果有注解修饰,反射运行一下该方法
//isAnnotationPresent(Class
extendsAnnotation>annotationClass)
if(m.isAnnotationPresent(MyTest.class)){
//有注解修饰
//这里并不是一个方法都没运行,而是一个注释都没找到
m.invoke(d2,null);
}
}
}
@MyTest
publicvoidrun1(){
System.out.println("run1");
}
@MyTest
publicvoidrun2(){
System.out.println("run2");
}
publicvoidrun3(){
System.out.println("run3无注解修饰");
}
}
1.3案例二:
使用Servlet3.0技术完成文件的上传:
(Servlet3.0技术要求理解掌握,文件上传原理掌握完全)
1.3.1需求:
1.3.2分析:
1.3.2.1技术分析:
【Servlet3.0】
Servlet3.0与Servlet2.5:
*Servlet3.0需要运行在tomcat7以上的服务器中.
*Servlet3.0以后web.xml就不是必须的.[创建项目时没有web.xml了]
1.Servlet3.0支持注解开发.
2.提供异步多线程请求.(强调多线程)
3.支持文件上传.【2.5文件上传必须引入第三方插件】
【Servlet3.0支持注解开发】
使用@WebServlet替换web.xml中配置的Servlet:
@WebServlet(urlPatterns="/ServletDemo1",loadOnStartup=2,initParams=@WebInitParam(name="username",value="root"))
使用@WebListener替换web.xml中监听器的配置:
@WebListener
使用@WebFilter替换web.xml中的过滤器的配置:
@WebFilter(urlPatterns="/*")
过滤器的执行顺序按照过滤器的名字执行,例如Filter01的执行顺序优先于Filter02
Servlet3.0使用注解开发,避免咱们去web.xml中大海捞针
【Servlet3.0支持异步多线程处理请求-了解原理,不要求写代码】
传统的Servlet2.5以及未设置支持异步的servlet3.0:
同步,单线程
使用的是多线程的方式处理的,将传统的方式一次请求的非常耗时的操作,分成多个线程去处理.
需要在Servlet上添加一个属性:
@WebServlet(urlPatterns="/ServletDemo2",asyncSupported=true)
注:
对应的过滤器也必须是支持异步
@WebServlet(urlPatterns="/demo2",asyncSupported=true)
publicclassDemo2extendsHttpServlet{
privatestaticfinallongserialVersionUID=1L;
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
AsyncContextcontext=request.startAsync(request,response);
//开启异步
context.start(newMyRunnable("一"));
for(chari='a';i<='z';i++){
System.out.println("主"+":
"+i);
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
//异步完成
plete();
System.out.println("异步完成,以下代码就变成了同步单线程");
Runnablemy1=newMyRunnable("一");
my1.run();
for(chari='a';i<='z';i++){
System.out.println("主"+":
"+i);
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
publicclassMyRunnableimplementsRunnable{
privateStringname;
publicMyRunnable(Stringname){
this.name=name;
}
@Override
publicvoidrun(){
for(chari='a';i<='z';i++){
System.out.println(name+":
"+i);
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
【Servlet3.0的文件上传】
Ø文件上传:
文件上传:
指的是将本地的文件写到服务器上.
文件上传本质:
IO流
Ø文件上传浏览器三要素:
(浏览器的上传三步)
1.表单的提交的方式必须是POST.
2.表单中必须有一个文件上传项:
*
3.表单必须是上传表单。
表单的enctype属性的值必须是multipart/form-data
Ø文件上传的抓包分析:
未修改enctype属性的时候:
POST/WEB17_WEB/demo1/demo1.jspHTTP/1.1
Accept:
text/html,application/xhtml+xml,*/*
X-HttpWatch-RID:
22325-10011
Referer:
http:
//localhost:
8080/WEB17_WEB/demo1/demo1.jsp
Accept-Language:
zh-Hans-CN,zh-Hans;q=0.5
User-Agent:
Mozilla/5.0(WindowsNT6.3;WOW64;Trident/7.0;rv:
11.0)likeGecko
Content-Type:
application/x-www-form-urlencoded
Accept-Encoding:
gzip,deflate
Host:
localhost:
8080
Content-Length:
47
Connection:
Keep-Alive
Cache-Control:
no-cache
Cookie:
JSESSIONID=99CD51DA9A47D29200168968AD983E9E
upload=C%3A%5CUsers%5Capple%5CDesktop%5Caaa.txt
已经修改了enctype属性:
POST/WEB17_WEB/demo1/demo1.jspHTTP/1.1
Accept:
text/html,application/xhtml+xml,*/*
X-HttpWatch-RID:
22325-10026
Referer:
http:
//localhost:
8080/WEB17_WEB/demo1/demo1.jsp
Accept-Language:
zh-Hans-CN,zh-Hans;q=0.5
User-Agent:
Mozilla/5.0(WindowsNT6.3;WOW64;Trident/7.0;rv:
11.0)likeGecko
Content-Type:
multipart/form-data;boundary=---------------------------7e02e526160b66
Accept-Encoding:
gzip,deflate
Host:
localhost:
8080
Content-Length:
224
Connection:
Keep-Alive
Cache-Control:
no-cache
Cookie:
JSESSIONID=99CD51DA9A47D29200168968AD983E9E
-----------------------------7e02e526160b66
Content-Disposition:
form-data;name="upload";filename="C:
\Users\apple\Desktop\aaa.txt"
Content-Type:
text/plain
Helloshouyi
-----------------------------7e02e526160b66—
【文件上传的原理】
根据分割线将请求体的部分分成几块:
*判断每块是普通项还是文件上传项.
*普通项:
获得名称和值.
*文件上传项:
获得文件名和文件内容输入流.
【文件上传的技术】
JspSmartUpload:
jspSmartUpload组件是应用JSP进行B/S程序开发过程中经常使用的上传下载组件,它使用简单,方便。
现在我又为其加上了下载中文名字的文件的支持,真个是如虎添翼,必将赢得更多开发者的青睐。
-Model1年代的文件上传的工具.
FileUpload是Apachecommons下面的一个子项目,用来实现Java环境下面的文件上传功能,与常见的SmartUpload齐名.应用在Model2年代了.
Servlet3.0:
Struts2:
1.3.2.2步骤分析:
设计一个文件上传页面:
提交到Servlet:
●接收普通项:
request.getParameter();//仅有Servlet3.0文件上传会使用该方法
●接收上传项:
Part:
通过Part对象中的方法完成文件的上传.
1.3.3代码实现
@WebServlet(urlPatterns="/upload")
@MultipartConfig
publicclassUploadServletextendsHttpServlet{
privatestaticfinallongserialVersionUID=1L;
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
request.setCharacterEncoding("utf-8");
//获取普通表单信息
Stringdesc=request.getParameter("desc");
System.out.println("desc:
"+desc);
//获取上传表单项信息
Partpart=request.getPart("photo");
System.out.println("文件大小:
"+part.getSize());
System.out.println("文件的类型:
"+part.getContentType());
System.out.println("上传表单项的name属性:
"+part.getName());
//获取文件信息
InputStreamis=part.getInputStream();
//写到服务器的硬盘上
//写到发布目录upload文件夹中
Stringuploadpath=this.getServletContext().getRealPath("/upload");
//获取文件名
//form-data;name="upload";filename="C:
\Users\apple\Desktop\aaa.txt"
Stringheader=part.getHeader("Content-Disposition");
Stringfilename=this.getFileName(header);
//因为不同浏览器提交的文件名不同的
//需要获取真实的文件名
Stringrealfilename=this.getRealFileName(filename);
OutputStreamout=newFileOutputStream(uploadpath+"/"+realfilename);
intlen=-1;
byte[]b=newbyte[1024];
while((len=is.read(b))!
=-1){
out.write(b);
out.flush();
}
out.close();
is.close();
}
//获取文件名方法
//form-data;name="upload";filename="C:
\Users\apple\Desktop\aaa.txt"
privateStringgetFileName(Stringheader){
intindex=header.lastIndexOf("filename=\"");
returnheader.substring(index+10,header.length()-1);
}
}
1.3.4总结:
1.3.4.1获取真实的文件名问题:
因为火狐浏览器会上传文件名.扩展名
IE10会上传绝对路径
//获取真实的文件名----处理绝对路径
//C:
\Users\apple\Desktop\aaa.txt
privateStringgetRealFileName(Stringfilename){
intindex=filename.lastIndexOf("\\");
returnfilename.substring(index+1);
}
1.3.4.2文件名重名的问题:
上传的文件名同名:
覆盖
思路:
1、网站流量不大,可以去遍历文件夹内容,如果有同名,自拍照
(1)自拍照
(2)
2、可以在文件名后面去拼接毫秒值自拍照_28917897自拍照_12789127
3、可以在文件名后面拼接随机数Math.random()自拍照_28917897自拍照_12789127
UUID随机数+文件名
//文件名重名处理---生成唯一的文件名
privateStringgetUUIDFileName(Stringrealfilename){
Stringrandomuuid=UUID.randomUUID().toString();
randomuuid=randomuuid.replaceAll("-","");
returnrandomuuid+"_"+realfilename;
}
1.4案例三:
使用动态代理的方式统一网站的字符集编码
1.4.1需求:
在一个表单中分别使用get和post提交到Servlet中,在Servlet中直接调用getParameter方法解决中文乱码的问题!
!
!
1.4.2分析:
1.4.2.1技术分析:
【动态代理】
增强某个类的方法
1、继承需要控制类的构造new
会占用宝贵的继承位
2、装饰者需要实现被增强类的接口
需要被增强类的引用
接口中方法极多,需要实现大量无关的方法
3、动态代理需要被增强类的接口
如果接口中方法极多,不需要去实现任何无关方法
增强类中的某些方法。
SpringAOP
代理:
【入门案例】
【注意事项】
1、invoke的返回值,就是代理对象执行方法的返回值
2、如果实现类中定义了某个方法,而接口中未定义,动态代理无法去代理该方法。
【如果想要代理某个方法,那么就在接口中定义】
1.4.3代码实现:
packagecom.itheima.encoding;
importjava.io.IOException;
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy;
importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterC
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WEB17 基础 加强 笔记