Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。(百度百科)
目录
下载文件:
上传文件:
?BaseServlet功能:
Cookie
请求转发与重定向
?
下载文件:
设置好response的相应头格式
response.setContentType("application/force-download");
response.setHeader("Content-Disposition","attachment;filename=\""+filename+"\"");
关于响应头格式csdn上有很多优秀博主有详细介绍: @大小鱼鱼鱼与鱼.
文件的读取位置没放对很头疼,我把文件放置在这个位置:
@WebServlet( "/downServlet")
public class DownServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
OutputStream out;
InputStream in;
ServletContext servletContext = getServletContext();
String filename = request.getParameter("filename");//获取请求文件名
if(filename==null){
out= response.getOutputStream();
out.write("Please input filename".getBytes("utf-8"));
out.close();
return;
}
in=servletContext.getResourceAsStream("/WEB-INF/img/" +filename);//这里文件的路径要注意写对
//设置响应正文的MIME类型
response.setContentType("application/force-download");
response.setHeader("Content-Disposition","attachment;filename=\""+filename+"\"");
out= response.getOutputStream();
int len=0;
byte[]bys=new byte[1024];
while((len=in.read(bys))!=-1){
out.write(bys,0,len);//将输入流写到页面上
}
in.close();
out.close();
in= ServletContext.class.getResourceAsStream("/img/"+filename);
}
}
html页面很简陋
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>down</title>
</head>
<body>
<a href="/downServlet?filename=1.jpg" onclick="">点击下载图片1</a> <br>
<a href="/downServlet?filename=2.jpg" onclick="">点击下载图片2</a>
</body>
</html>
效果:
上传文件:
使用fileuploadjar包配合 IO jar包,里面有工厂类.
同样要上传文件位置也要写对,这里我直接用绝对路径能省点事.
private String filePath="E:\\develop\\files\\store";//文件放置目录
private String tempFilePath="E:\\develop\\files\\store";//临时目录
@WebServlet("/upload")
public class upload extends HttpServlet {
private String filePath="E:\\develop\\files\\store";//文件放置目录
private String tempFilePath="E:\\develop\\files\\store";//临时目录
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("被访问了...");//测试
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
PrintWriter outNet = response.getWriter();
try {
//创建一个基于硬盘的fileitem工厂
DiskFileItemFactory factory=new DiskFileItemFactory();
//设置想硬盘写数据时所用的缓冲区的大小 此处4M
factory.setSizeThreshold(4*1024*1024);
//设置临时目录
factory.setRepository(new File(tempFilePath));
//创建一个文件上传处理器
ServletFileUpload upload=new ServletFileUpload(factory);
//设置允许上传的文件的最大尺寸 此处4M
upload.setSizeMax(4*1024*1024);
List Items=null;
//解析request对象的复合表单数据 返回一个fileItem对象的List集合
request.setCharacterEncoding("utf-8");
Items = upload.parseRequest(request);
Iterator iter=Items.iterator();
while(iter.hasNext()){
//遍历该集合 拿到数据
FileItem item=(FileItem) iter.next();
if(item.isFormField()){
//处理普通的表单域
processFormField(item,outNet);
}
else {
//处理上传文件
processUploadFile(item,outNet);
}
}
outNet.close();
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private void processFormField(FileItem item, PrintWriter outNet) {
String name = item.getFieldName();//获取表单域的名字
String string = item.getString();//获取表单域
outNet.println(name+":"+string+"\r\n");
}
private void processUploadFile(FileItem item, PrintWriter outNet) throws Exception {
String Filename = item.getName();//获取包括路径在内的文件名字
int index = Filename.lastIndexOf("\\");
Filename=Filename.substring(index+1,Filename.length());//分割得到文件名
long size = item.getSize();
if(Filename.equals("")&&size==0)return;//不存在就直接return
File uploadFile=new File(filePath+"/"+Filename);//创建一个新文件
item.write(uploadFile);//写入新文件
outNet.println(Filename+"is saved");
outNet.println("The size of "+Filename+" is "+size/1000+" kb\r\n");
}
}
html页面也是写得比较简陋,只为实现功能
注意请求头格式:enctype="multipart/form-data"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upload</title>
</head>
<body>
<form name="uploadForm" method="post"
enctype="multipart/form-data" action="upload">
<table>
<tr>
<td><div align="right">User Name:</div></td>
<td><input type="text" name="username" size="30"></td>
</tr>
<tr>
<td><div align="right">Upload File1:</div></td>
<td><input type="file" name="file1" size="30"></td>
</tr>
<tr>
<td><div align="right">Upload File2:</div></td>
<td><input type="file" name="file2" size="30"></td>
</tr>
<tr>
<td><input type="submit" name="submit" value="upload"></td>
<td><input type="reset" name="reset" value="reset"></td>
</tr>
</table>
</form>
</body>
</html>
效果:
看看效果:可以看到上传成功了.
硬盘目录也出现这两个上传的文件了:
?BaseServlet功能:
减少Servlet的数量,现在是一个功能一个Servlet,将其优化为一个模块一个Servlet,相当于在数据库中一张表对应一个Servlet,在Servlet中提供不同的方法,完成用户的请求。也就是说写一个Servlet就够了,其他的servlet写成方法就可以直接访问.原理是反射-->反射的基本使用
关于BaseServlet详细介绍:@阿顾同学
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String requestURI = req.getRequestURI();//获取请求的路径
// System.out.println(requestURI);// /userServlet/add
//获取方法名
String methodName = requestURI.substring(requestURI.lastIndexOf('/') + 1);
// System.out.println(methodName); //add
// System.out.println(this);//web.servlet.UserServlet@38e182e5
//可以看到这里的this是从URL过来的对象而不是这个baseServlet
try {
//通过反射获取方法
Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this,req,resp);//这里的this是访问它的那个方法
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
下面的cookie测试servlet 和请求转发/重定向就是用了BaseServlet.
Cookie
是在客户端访问web组件时,服务器响应给客户端,给客户端硬盘上存放的信息.
Cookie类。 Response.addCookie
@WebServlet( "/test/*")
public class UserServlet extends BaseServlet {
private int count=0;
public void cookieTest(HttpServletRequest request, HttpServletResponse response) throws IOException {
//测试cookie
response.setContentType("text/plain");
//获取http请求中所有的cookie
Cookie[] cookies = request.getCookies();
if(cookies!=null){
//访问每个cookie
for(int i=0;i<cookies.length;i++){
//向页面输出cookie信息
response.getWriter().println("Cookie name :"+cookies[i].getName());//向页面输出cookie名
response.getWriter().println("Cookie values :"+cookies[i].getValue());//向页面输出cookie值
response.getWriter().println("Cookie MAX age :"+cookies[i].getMaxAge()+"\r\n");//向页面输出cookie有效期
}
}else {
response.getWriter().println("No Cookies!");
}
//向客户端写入cookie
response.addCookie(new Cookie("cookieName"+count,"cookieValue"+count));
count++;
}
}
第一遍访问,没有cookie?
后面几次就有了。
请求转发与重定向
简单的说,两者的功能都是实现从源web组件跳转到目标web组件。
request的请求转发,源组件和目标组件处理的是同个客户请求,他们共享同个request和response。
Response的重定向,是在httpServletResponse接口中定义的,由http协议规定的。源组件和目标组件不共享request,所以不共享数据。源组件要是有生成响应结果,客户端不会接受到,用了重定向,客户端接收的将是目标组件的响应结果。 二者的使用条件是,需要共享数据时用请求转发,否则使用重定向。
请求转发测试:
public void requestTest1(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//源组件
String msg="This a msg from requestTest1";
request.setAttribute("msg",msg);//存储信息
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/test/requestTest2");//写上目标地址,请求分发器实现转发
requestDispatcher.forward(request,response);//将这两个发送过去
//不应该在源组件这里提交相应结果,这里的响应结果不会被发送到客户端
response.getWriter().println(msg+" now is: test1");
}
public void requestTest2(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//目标组件
String msg = (String) request.getAttribute("msg");//从源组件得到该信息
response.getWriter().println(msg+" now is: test2");
}
看看结果:
?
?重定向测试:
public void responseTest1(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//源组件
String msg="This a msg from responseTest1";
request.setAttribute("msg",msg);//存储信息
response.sendRedirect("test/responseTest2");//重定向过去
}
public void responseTest2(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//目标组件
String msg = (String) request.getAttribute("msg");//从源组件得到该信息
System.out.println("重定向能否收到信息?"+msg);
response.getWriter().println("I am in responseTest2 now");
}
?看看结果:
?可以看到,重定向的目标组件并没有收到源组件的信息
可以看到成功转发到目标组件这边.
不知不觉就写了两天...
|