一:文件上传
01.文件上传准备
1):上传控件所在的<form>表单的method,必须POST:
因为GET方式的数据大小不能超过2kb,而POST没有大小限制.
2):上传控件得使用type为file的类型.<input type="file" name="headImg"/>
3):表单的编码方式必须是二进制编码.<form enctype="multipart/form-data">
注意:使用二进制的编码之后form enctype="multipart/form-data">,在Servlet中再也不能通过request.getParameter方法来获取参数了,设置编码也没有效果
02.基于Apache FileUpload组件文件上传操作
依赖的jar:
1):commons-fileupload-1.2.2.jar
2):commons-io-1.4.jar
参考文档:
commons-fileupload-1.2.2\site\index.html
hello world版本,建议自己看着文档写一遍
@WebServlet("/upload")
public class UploadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse resp){
//解析和检查请求:请求方式是否是POST,请求编码是否是enctype="multipart/form-data"
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
if(!isMultipart){
return;
}
//1:创建FileItemFactory对象
//FileItemFactory是用来创建FileItem对象的.
//FileItem对象:form表单中的表单控件的封装
try {
FileItemFactory factory = new DiskFileItemFactory();
//2:创建文件上传处理器
ServletFileUpload upload = new ServletFileUpload(factory);
//3:解析请求
List<FileItem> items = upload.parseRequest(req);
for (FileItem item : items) {
String fieldName = item.getFieldName();//获取表单控件的name属性值(参数名)
if(item.isFormField()){
//普通表单控件
String value = item.getString("UTF-8");//获取当前普通表单控件的参数值
System.out.println(fieldName+"--"+value);
}else{
//表单上传控件
System.out.println(fieldName+"+"+item.getName());
item.write(new File("D:/",item.getName()));//把二进制数据写到哪一个文件中
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
03.上传文件的名称处理
1):文件名处理:
IE6问题:通过FileItem.getName方法获取上传文件的名称,此时会带有路径:
其他浏览器:outman.png. IE6:C:/123/outman.png.
使用FilenameUtils.getName(path);
上传文件名称:给上传的文件起唯一的名称:UUID.
String fileName = UUID.randomUUID().toString()+"."+FilenameUtils.getExtension(item.getName());
上传文件的保存路径:一般的,把上传文件保存到应用里面.
2):缓存大小和临时目录:
超过多少就不直接存放与内存了(缓存大小):默认值是10KB.
不放在内存,会放在哪个位置(临时目录):默认Tomcat根/temp目录.不建议修改
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓存大小
factory.setSizeThreshold(20*1024);
//设置临时目录
factory.setRepository(repository);
3):文件类型约束:
//获取当前上传文件的MIME类型
String mimeType = super.getServletContext().getMimeType(item.getName());
servlet代码:
//允许接受的图片类型
private static final String ALLOWED_IMAGE_TYPE="png;gif;jpg;jpeg";
//上传文件的拓展名
String ext = FilenameUtils.getExtension(item.getName());
String[] allowedImageType = ALLOWED_IMAGE_TYPE.split(";");
//当前上下文的类型不在图片允许的格式之内
if(!Arrays.asList(allowedImageType).contains(ext)){
req.setAttribute("errorMsq","亲,请上传图片文件");
req.getRequestDispatcher("/input.jsp").forward(req,resp);
return ;//结束方法
}
jsp的代码:
<span style="color: red;">${errorMsg}</span>
4)抽取文件上传工具方法.
@WebServlet("/upload")
public class UploadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
FileUtil.upload(req);
} catch (LogicException e) {
String errorMsge = e.getMessage();
req.setAttribute("errorMsg", errorMsge);
req.getRequestDispatcher("/input.jsp").forward(req, resp);
}
}
}
public class FileUtil {
//允许接收的图片类型
private static final String ALLOWED_IMAGE_TYPE = "gif;jpq;jpeg";
public static void upload(HttpServletRequest req) {
try{
......
if (!list.contains(ext)) {
throw new LogicException("亲!请上传正确的图片格式!");
}
......
} catch (LogicException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
}
}
}
5):上传文件大小约束:
情况1: 单个文件超过指定的大小. upload.setFileSizeMax(1024 * 1024 * 2);
情况2: 该次请求的全部数据超过指定的大小 upload.setSizeMax(1024*1024*3)
catch (FileSizeLimitExceededException e) {
throw new LogicException("亲,单个文件大小不能超过2M",e);
} catch (SizeLimitExceededException e) {
throw new LogicException("亲,该次请求的大小不能超过3M",e);
} catch (LogicException e) {
throw e;//继续抛出异常给调用者(UploadServlet)
} catch (Exception e) {
e.printStackTrace();
}
6):使用Map封装请求信息(拓展):
@Data
public class User {
private String username;
private String email;
private String imageUrl;//图片保存的路径:/upload/123.png JSP: <img src="${user.imageUrl}"/>
private String imageName;//图片的原始名称
}
@Data
public class CFiled {
private String imageUrl;
private String imageName;
}
@WebServlet("/upload")
public class UploadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
User user = new User();
HashMap<String,String> map = new HashMap<>();
HashMap<String,CFiled> binaryMap = new HashMap<>();
FileUtil.upload(req,map,binaryMap);
user.setEmail(map.get("email"));
user.setUsername(map.get("username"));
user.setImageName(binaryMap.get("headimg").getImageName());
user.setImageUrl(binaryMap.get("headimg").getImageUrl());
System.out.println(map);
System.out.println(binaryMap);
System.out.println(user);
req.setAttribute("u", user);
req.getRequestDispatcher("/show.jsp").forward(req, resp);
} catch (LogicException e) {
String errorMsge = e.getMessage();
req.setAttribute("errorMsg", errorMsge);
req.getRequestDispatcher("/input.jsp").forward(req, resp);
}
}
}
public class FileUtil {
private static final String ALLOWED_IMAGE_TYPE = "png;gif;jpq;jpeg";
public static void upload(HttpServletRequest req, HashMap<String,String> map, HashMap<String,CFiled> binarytMap) {
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
if (!isMultipart) {
return;
}
try {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(1024 * 1024 * 2);//2M
upload.setSizeMax(1024*1024*3);//3M
List<FileItem> items = upload.parseRequest(req);
for (FileItem item : items) {
String fieldName = item.getFieldName();//获取表单控件的name属性值(参数名)
if (item.isFormField()) {
//普通表单控件
String value = item.getString("UTF-8");//获取当前普通表单控件的参数值
map.put(fieldName, value);
} else {
//--------------------------------------------
//上传文件的拓展名
String ext = FilenameUtils.getExtension(item.getName());
String[] allowedImageType = ALLOWED_IMAGE_TYPE.split(";");
List<String> list = Arrays.asList(allowedImageType);
if (!list.contains(ext)) {
throw new LogicException("亲!请上传正确的图片格式!");
}
//--------------------------------------------
//表单上传控件
System.out.println("上传文件的名称:" + FilenameUtils.getName(item.getName()));
String fileName = UUID.randomUUID().toString() + "." + FilenameUtils.getExtension(item.getName());
String dir = req.getServletContext().getRealPath("/upload");
item.write(new File(dir, fileName));//把二进制数据写到哪一个文件中
CFiled CFiled = new CFiled();
CFiled.setImageName(FilenameUtils.getName(item.getName()));
CFiled.setImageUrl("/upload/"+fileName);
binarytMap.put(fieldName,CFiled);
}
}
} catch (FileSizeLimitExceededException e) {
throw new LogicException("亲,单个文件大小不能超过2M",e);
} catch (SizeLimitExceededException e) {
throw new LogicException("亲,该次请求的大小不能超过3M",e);
} catch (LogicException e) {
throw e;//继续抛出异常给调用者(UploadServlet)
} catch (Exception e) {
e.printStackTrace();
}
}
}
二:文件的下载
IE和非IE的文件名乱码处理:
list.jsp文件:
<h3>下载资源列表</h3>
<a href="/down?filename=butter.rar">butter.rar</a><br/>
<a href="/down?filename=超人superman.rar">超人Superman</a>
Servlet文件:
@WebServlet("/down")
public class DownloadServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//0:权限检查/积分检查
//1:获取被下载的资源文件名称
String fileName = req.getParameter("filename");
if(fileName!=null && !"".equals(fileName.trim())){
fileName = new String(fileName.getBytes("ISO-8859-1"),"utf-8");
System.out.println(fileName);
}
//2:从服务器中找到被下载资源的绝对路径
String realPath = super.getServletContext().getRealPath("/WEB-INF/download/"+fileName);
//=======================================
//①:告诉浏览器不要直接打开文件,而是弹出下载框,保存文件
resp.setContentType("application/x-msdownload");
//②:设置下载文件的建议保存名称
String userAgent = req.getHeader("User-Agent");
if(userAgent.contains("like")){
//IE
fileName = URLEncoder.encode(fileName,"UTF-8");
}else{
//非IE
fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
}
resp.setHeader("Content-Disposition","attachment;filename="+fileName);
//=======================================
//3:磁盘中的文件读取到--->程序中来--->浏览器(拷贝操作)
Files.copy(Paths.get(realPath), resp.getOutputStream());
}
}
三: I18N国际化
04.国际化了解上
软件的本地化,一个软件在某个国家或地区使用时,采用该国家或地区的语言,数字,货币,日期等习惯.
软件的国际化:软件开发时,让它能支持多个国家和地区的本地化应用.使得应用软件能够适应多个地区的语言和
文化习俗的习惯.随用户区域信息而变化的数据称为本地信息敏感数据.例如数字,货币等数据.应用程序的国际
化就是在应用软件的设计阶段,使软件能够支持多个国家和地区的使用习惯.
05.国际化了解下
@Test
public void test1() throws Exception {
System.out.println(Locale.CHINA);
System.out.println(Locale.US);
System.out.println(Locale.FRANCE);
System.out.println(Locale.TAIWAN);
}
@Test
public void testFormat() throws Exception {
System.out.println(new Date());
String format = DateFormat.getInstance().format(new Date());
System.out.println(format);
}
//¥123,456,789.89
//123?456?789,89 €
//?123,456,789.89
//$123,456,789.89
@Test
public void testNumberFormat() throws Exception {
Double money = 123456789.89;
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(format.format(money));
}
public static void main(String[] args) {
String pattern = "我是{3},你是{5},他是{4},她是{2},它是{1}";
String str = MessageFormat.format(pattern, "A","B","C","D","E");
System.out.println(str);
}
@Test
public void testSql() throws Exception {
String sql = "SELECT * FROM {0} {1}";
String ret = MessageFormat.format(sql, "product","WHERE productName LIKE = ?");
System.out.println(ret);
}
public static void main(String[] args) {
//ResourceBundle可以获取资源文件,获取其中的信息
ResourceBundle rb = ResourceBundle.getBundle("app",Locale.CHINA);
String username = rb.getString("username");
String company = rb.getString("company");
System.out.println(username+"---->"+company);
}
知识点:
1):基于Apache 的fileUploaed组件完成文件的上传操作.
2):文件上传做控制:
1):文件名处理.
2):上传文件的类型约束.
3):上传文件的大小限制.
3):文件下载操作.
-----------------------------------------------
任务:
1):高级查询和分页查询,巩固,加强.
2):去淘宝,去京东体验购物车.