您的位置:首页 > 编程语言 > Java开发

注解及Servlet3.0的一些新特性及简单的文件上传

2018-03-12 23:06 399 查看
注解

JDK中提供的注解

自定义注解
自定义注解的属性

文件上传问题的解决

Servlet3.0的新特性(Tomcat 7以上的版本才支持)
Servlet3.0的注解开发

文件上传原理分析

文件上传问题:文件重名和一个目录下存放的文件过多

Servlet3.0异步请求

注解

一般来说,注释是给程序员看的,而注解是给虚拟机看的。(让虚拟机看到程序中的注解,注解代表程序的一些特殊的功能。)

JDK中提供的注解

@Override:描述子类重写父类的方法

JDK1.5版本的时候 该注解只能应用在 类的继承上,JDK1.6版本的时候 该注解可以应用在 类的实现上。

@SuppressWarnings:压制警告

@SuppressWarnings(“”),括号内有很多取值,但可以直接写一个”all”全部压制。注解中value属性是String[] value。

@Deprecated:描述方法过时

自定义注解

定义类:class

定义接口:interface

定义枚举:enum

enum Color {
RED,BLUE,GREEN;
}


定义注解:@interface

@interface Anno1{
int i();
boolean b() default false;
String s();
// Date d();
Class c();
//注解属性使用注解的用法参考下面
Anno2 anno2();
Color color();
String[] arrs();
}

@interface Anno2{
String value();
int i() default 1;
}

@Anno1(i=1,s="abc",c=AnnotationDemo1.class,anno1=@Anno1,color=Color.RED,arrs={"aa","bb"})
@Anno2("abc")
public class AnnotationDemo1 {

}

@WebServlet(urlPatterns="/ServletDemo1",loadOnStartup=2,initParams={@WebInitParam(name="username",value="root"),@WebInitParam(name="password",value="123")})
public class ServletDemo1 extends HttpServlet{

}


@WebServlet(urlPatterns=”/ServletDemo1”,loadOnStartup=2,
initParams={@WebInitParam(name="username",value="root"),@WebInitParam(name="password",value="123")}
)

public class ServletDemo1 extends HttpServlet{

}

自定义注解的属性

基本数据类型:

String类型:

Class类型:

注解类型:

枚举类型:

以上类型的一维数组:

特殊的属性名称:value

如果定义注解的时候,只出现了value属性, 那么使用注解的时候value属性可以省略的(@SuppressWarnings(“all”)注解只出现了value属性,类型是字符串数组).如果出现了value属性,也出现了其他属性,当其他属性都有默认值得时候,使用注解的时候value属性也可以省略。

元注解

自定义注解默认存在于源码阶段,需要让注解存在的时间更长.使用元注解:(只用于修饰其他的注解)( 让注解存在的时间更长使用
@Retention(value=RetentionPolicy.[SOURCE|CLASS|RUNTIME]),可以看出value的取值是枚举类型)


注解的使用

一般注解的使用是要结合反射来一起使用的,在Methed类中有

返回值类型方法名解释
<
T extends Annotation
>
T
getAnnotation(Class
<
T
>
annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
Annotation[]getDeclaredAnnotations()返回直接存在于此元素上的所有注释。
从类 java.lang.reflect.AccessibleObject 继承的方法中有以下两个

返回值类型方法名解释
Annotation[]getAnnotations()返回此元素上存在的所有注释。
booleanisAnnotationPresent(Class annotationClass)如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。

文件上传问题的解决

知道的文件上传技术

Servlet3.0:注解开发,文件上传,异步请求.

JSPSmartUpload:嵌入到JSP中完成文件上传.主要用于Model1年代的.

FileUpload:Apache的文件上传组件.

Struts2:底层是FileUpload.

文件上传的要素

表单的提交的方式必须是POST.

表单中需要有文件上传的表单元素:这个元素这个元素必须有name属性和值
<input type=”file” name=”upload”>


表单的enctype属性的值必须是
multipart/form-data
.

Servlet3.0的新特性(Tomcat 7以上的版本才支持)

Servlet3.0相比Servlet2.5提供了三个新特性

注解开发 :方便

文件上传 :有些API不是特别全.

异步请求 :

Servlet3.0的注解开发

@WebServlet

@WebListener

@WebFilter

文件上传原理分析

没有设置enctype属性的时候:只能获得文件的名称,而没有文件内容,如下图



设置enctype属性为multipart/form-data:获得到文件名及文件内容,如下图



文件上传的原理图



使用Servlet3.0实现文件上传。代码如下

<body>
<h1>文件上传的页面</h1>
<!--
* 表单的提交的方式必须是POST.
* 表单中需要有文件上传的表单元素:这个元素这个元素必须有name属性和值:<input type=”file” name=”upload”>
* 表单的enctype属性的值必须是multipart/form-data.
-->
<form action="${ pageContext.request.contextPath }/UploadServlet" method="post" enctype="multipart/form-data">
<table border="1" width="600">
<tr>
<td>文件描述</td>
<td><input type="text" name="filedesc"></td>
</tr>
<tr>
<td>文件上传</td>
<td><input type="file" name="upload"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="上传"></td>
</tr>
</table>
</form>
</body>


/**
* 文件上传的Servlet
*/
@WebServlet("/UploadServlet")
@MultipartConfig
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 接收普通数据:
request.setCharacterEncoding("UTF-8");
String filedesc = request.getParameter("filedesc");
System.out.println("文件描述"+filedesc);
// 接收文件:
Part part = request.getPart("upload");

long size = part.getSize();// 获得文件大小:
System.out.println("文件大小:"+size);
String name = part.getName();
System.out.println("文件表单中的name属性的名称"+name);
// 获得文件名:
String header = part.getHeader("Content-Disposition");
int idx = header.lastIndexOf("filename=\"");
String fileName = header.substring(idx+10, header.length()-1);
//IE浏览器不行,加上以下代码
//String[] split = fileName.split("//");
//fileName = split[split.length-1];
System.out.println("文件名:"+fileName);
// 获得文件内容:
InputStream is = part.getInputStream();
// 获得upload的路径:
//项目根路径下不安全,最好存到web-inf目录下
String path = this.getServletContext().getRealPath("/WEB-INF/upload");
// 获得文件的唯一文件名:
String uuidFileName = UUIDUtils.getUUIDFileName(fileName);
String realPath = path+UploadUtils.getPath(uuidFileName);
File file = new File(realPath);
if(!file.exists()){
file.mkdirs();
}
OutputStream os = new FileOutputStream(realPath+"/"+uuidFileName);
byte[] b = new byte[1024];
int len = 0;
while((len = is.read(b))!=-1){
os.write(b, 0, len);
}
is.close();
os.close();
}


文件上传问题:文件重名和一个目录下存放的文件过多

文件重名

使用UUID生成随机的唯一文件名

同一目录下文件过多

一个目录下文件过多,导致打开都很慢,更别说是读写操作.

目录分离:

按时间分 :一个月一个目录,一个星期一个目录,一天一个目录

按数量分 :一个目录下存5000个文件,创建一个新的目录,再去存放.

按用户分 :为每个用户创建一个单独目录 存放文件.

按目录分离算法分 :

使用唯一文件名.hashCode(); – 得到一个代表当前这个文件的int类型值.

int类型占4个字节32位.可以让hashCode值&0xf; 得到一个int值,用这个int值作为一级目录.

让hashCode右移4位 &0xf ;得到一个int值,用这个int值作为二级目录.依次类推.

原理图如下



Servlet3.0异步请求

/**
* 异步请求的Servlet
*/
@WebServlet(urlPatterns="/AsyncServlet",asyncSupported=true)
public class AsyncServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext context = request.startAsync(request, response);
context.start(new MyRunnable(context));
for(int i = 1;i<=10;i++){
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

class MyRunnable implements Runnable{
private AsyncContext context;
public MyRunnable(AsyncContext context) {
this.context = context;
}
@Override
public void run() {
for(char i='a';i<='z';i++){
try {
context.getResponse().getWriter().println(i);
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java Servlet 注解