六、上传支持
1、上传
上传对表单的要求
method="post"
enctype="multipart/form-data",默认值是application/x-www-form-urlencoded
<input type="file" name="必须给"/>
上传Servlet的使用
request.getParameter()不能再用
request.getInputStream()使用这个来获取整个表单的数据
commons-fileupload
创建工厂
创建解析器
使用解析器来解析request对象,得到List<FileItem>
Servlet3.0对上传提供了支持
表单不变
在Servlet中不需要再使用commons-fileupload,而是使用Servlet3.0提供的上传组件接口
上传的步骤
使用request.getPart("字段名"),得到Part实例
Part:
String getContentType:获取上传文件的MIME类型
String getName():获取表单项的名称,不是文件名称
String getHeader(String header):获取指定头的值
long getSize():获取上传文件的大小
InputStream getInputStram():获取上传文件的内容
void write(String fileName):把上传文件保存到指定路径下
默认Servlet是不支持使用上传组件的:需要给Servlet添加一个注解:@MultipartConfig
没有提供获取上传文件名称的方法:
需要自己从Content-Disposition头中获取
动态代理
1、一个方法
方法的作用:在运行时,动态创建一组指定的接口的实现类对象。(在运行时,创建实现了指定的一组接口的对象)
interface A{
}
interface B{
}
Object o = 方法(new Class[]{A.class,B.class})
o实现了A和B两个接口。
request HttpServletRequest
class MyClass implements A,B{}
new MyClass();
Object proxyObject = Proxy.newProxyInstance(ClassLoader classLoader,Class[] interfaces,InvocationHandler h)
1、方法作用:动态创建实现了interface数组中所有指定接口的实现类对象
参数:
1、ClassLoader:类加载器。
用来加载类的,把.class文件加载到内存中,形成Class对象
2、Class[] interfaces:指定要实现的接口们
3、InvocationHandler:代理对象的所有方法(个别不会执行,getClass())都会调用InvocationHandler的invoke()方法
2、动态代理作用
最终还是学习AOP(面向切面编程),与装饰者模式有点相似,比装饰者模式还要灵活
InvocationHandler
public Object invoke(Object proxy,Method method,Object[] args);
这个invoke()方法在什么时候被调用
1、在代理对象被创建时。错误的
2、在调用代理对象所实现接口中的方法时。正确的
Object proxy:当前对象,即代理对象:在调用谁的方法
Method method:当前被调用的方法(目标方法)
Object[] args:实参
目标对象:被增强的镀锡
代理对象:需要目标对象,然后在目标对象上添加了增强后的镀锡
目标方法:增强的内容
增强、通知
织入
切点
@WebServlet(urlPatterns="/AServlet")
@MultipartConfig
public class AServelt extends HttpServlet {
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");//上传的文件名如果是乱码那么修改请求的编码尝试
/*
* 1、getParameter()方法可以使用了
*/
String username = req.getParameter("username");//可以使用了
/*
* 2、获取文件表单字段,对应的Part对象
*/
Part part = req.getPart("resume");
/*
* 3、从part中获取需要的数据
*/
//获取上传文件的MIME类型
System.out.println(part.getContentType());
//获取上传文件的字节数
System.out.println(part.getSize());
//获取文件字段名称
System.out.println(part.getName());
//获取头,头中包含了上传文件的名称
System.out.println(part.getHeader("Content-Disposition"));
//保存上传文件的名称
part.write("H:/xxx.png");
//截取上传文件名称
String filename = part.getHeader("Content-Disposition");
int index = filename.lastIndexOf("filename=\"")+10;
int end =filename.length()-1;
filename = filename.substring(index,end);
System.out.println(filename);
}
}
form.jsp
<form action ="<c:url value='/AServlet'/>" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br/>
简历<input type="file" name="resume"/><br/>
<input type="submit" value="zhuce"/>
</form>
public class Demo1 {
@Test
public void fun1(){
/*
* 三大参数
* 1、ClassLoader
* 方法需要动态生成一个类,这个类实现了A、B接口,然后创建这个类的对象
* 需要生成一个类,这个类也需要加载到方法区中,谁来加载,当然是ClassLoader。
*
* 2、Class[] interfaces
* 要实现的接口们
*
* 3.InvocationHandler
* 是调用处理器
* 敷衍它
*
* 代理对象的实现的所有接口中的方法,内容都是调用InvocationHandler的invoke()方法
*/
ClassLoader loader = this.getClass().getClassLoader();
InvocationHandler h= new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("哈哈,动态代理");
return "xxx";
}
};
//使用三大参数创建代理对象
Object o = Proxy.newProxyInstance(loader, new Class[]{A.class,B.class}, h);
//强转成A和B类型,成功了
A a = (A) o;
B b = (B) o;
// a.a();
// a.aa();
// a.getClass();
// a.hashCode();
// System.out.println(o.getClass().getName());
Object result = a.aaa("hi", 10);
System.out.println(result);
}
}
interface A{
public void a();
public void aa();
public Object aaa(String s,int i);
}
interface B{
public void b();
public void bb();
}
//服务员
public interface Waiter {
//服务
void serve();
}
public class ManWaiter implements Waiter {
public void serve() {
System.out.println("服务中");
}
}
public class Demo2 {
@Test
public void fun1(){
Waiter manWaiter = new ManWaiter();//目标对象
// Waiter waiter = new ManWaiter();
// waiter.serve();
/*
* 给出三个参数,来创建方法,得到代理对象
*/
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = {Waiter.class};
InvocationHandler h = new WaiterInvocationHandler(manWaiter);//参数manWaiter表示目标镀锡
//得到代理对象,代理对象就是在目标对象的基础上进行了增强的对象
Waiter waiterProxy = (Waiter) Proxy.newProxyInstance(loader, interfaces, h);
waiterProxy.serve();//前面添加"你好",后面添加"再见"
}
}
class WaiterInvocationHandler implements InvocationHandler{
private Waiter waiter;//目标对象
public WaiterInvocationHandler(Waiter waiter){
this.waiter = waiter;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("您好");
this.waiter.serve();//调用目标对象的目标方法
System.out.println("再见");
return null;
}
}