黑马商城06

黑马商城06

今日任务:
1.商品展示
2.添加商品(上传文件)

1.商品展示

	前端:
	 	携带当前页面页码请求后端
	 	后端数据拿来后拼串
    后端:
         把数据该查的查,该算的算,以Json格式返回

2.文件上传

文件上传?
	从客户端的计算机 传输 文件到服务器的计算机

	本质流传输的过程
///
	满足以下条件(java代码版)

	1.页面给一个form表单
	2.在表单有一个input type=file
	3.表单的提交方式 得是post 不能用get是因为数据拼在请求行里,对数据有大小限制
	4.修改表单的一个属性  enctype="application/x-www-form-urlencode"  修改为enctype="multipart/form-data"
	5.满足了以上四个条件 提交到后端服务器上 接收的时候  reqeust.getParameter|getParameterValues|getParameterMap 都将失效

	发现 虽然不能使用request.getParameter系列方法 但是发现数据是有规律的
	可以工具类 也是apache提供
		common-fileupload
		
    1.maven 添加依赖
	2.使用它的api 让它来帮助解析
		使用步骤(不需要记忆)-----框架里封装了 (以后开发 也不会写文件上传的服务器代码 为啥 最后解释)

		1.创建 文件磁盘工厂对象 
		2.创建一个上传解析对象 负责帮助我们解析 request中inputstream
		3.它解析完成 返回list集合  放着一个个的表单项
		4.使用了   遍历集合 取出一个个项


	小问题:
		文件名重复 覆盖问题  收到文件 文件名字自己取 保证唯一
		某个目录下 小文件太过问题 导致操作系统检索变慢
		分散目录
			随机分散目录

		删除临时文件
		item.delete()

代码实现

demo.html

    <!--enctype="multipart/form-data"-->
    <form action="/upload" method="post"  enctype="multipart/form-data" >
        用户名:<input type="text" name="username"><br>
        备注:<input type="text" name="desc"><br>
        头像:<input type="file" name="avatar"><br>
        身份证:<input type="file" name="IDCard"><br>
        <input type="submit" value="点我提交">
    </form>

UploadServlet

@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //不考虑文件框
        /*String username = request.getParameter("username");
        String desc = request.getParameter("desc");
        String avatar = request.getParameter("avatar");
        System.out.println("名字:"+username+"-描述:"+desc+"-头像:"+avatar);*/

        //获取请求 头 自己解析 太麻烦 我们使用 apache提供工具类
/*        String contentType = request.getHeader("Content-Type");
        String boundary=contentType.split("; ")[1].split("=")[1];
        System.out.println("该次请去分隔符是:"+boundary);

        ServletInputStream inputStream = request.getInputStream();
        //自己取数据
        BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream));
        String s1 = bf.readLine();
        System.out.println(s1);
        String s2 = bf.readLine();
        System.out.println(s2);*/

        //使用工具类
        //获取ip
        String remoteAddr = request.getRemoteAddr();
        System.out.println("欢迎我的朋友:"+remoteAddr+"来访问服务器");

        //目录将下面 封装了 放在一个方法里 返回一个返回值  返回map集合
        Map<String, String[]> map = parseRequest(request);

        Set<Map.Entry<String, String[]>> entries = map.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            System.out.println(entry.getKey()+"::::::::"+ Arrays.toString(entry.getValue()));
        }


        response.getWriter().print("ok");


    }
    public Map<String,String[]> parseRequest(HttpServletRequest request){
        //返回一个map集合
        Map<String,String[]> result = new HashMap<>();

        try {
            //1.创建 文件磁盘工厂对象
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            //2.创建一个上传解析对象 负责帮助我们解析 request中inputstream
            ServletFileUpload parser = new ServletFileUpload(diskFileItemFactory);
            //3.它解析完成 返回list集合  放着一个个的表单项
            List<FileItem> items = parser.parseRequest(request);
            //4.使用了   遍历集合 取出一个个项
            for (FileItem item : items) {
                //获取表单项的名字
                String parameterName = item.getFieldName();

                //判断表单是否是普通文本字段
                if(item.isFormField()){
                    //是普通项  关心她的值
                    String paramValue = item.getString("utf-8");

                    /*if(result.containsKey(parameterName)){

                    }*/
                    //这里注意有坑,当一个表单项有多个值的时候,这样写不行
                    result.put(parameterName,new String[]{paramValue});
                }else{
                    //文件项 关心就是 文件对应 的流
                    //文件的名字
                    String fileName = item.getName();

                    //以流的形式返回上传文件的数据内容
                    InputStream in = item.getInputStream();
                    //创建  分散二级目录
                    String secondDir = UploadUtil.randDir();
                    //电脑文件路径+随机目录
                    String storePath=UploadUtil.BaseDir()+secondDir;
                    //检查是否存在 有 直接用 没有创建
                    UploadUtil.mustExist(storePath);
                    //获取随机文件名
                    String uuidName = UploadUtil.getUUIDName(fileName);
                    //创建输出流
                    FileOutputStream out = new FileOutputStream(storePath + uuidName);

                    byte[] bf=new byte[1024];

                    int len=0;
                    while((len=in.read(bf))!=-1){
                        //写到输出流
                        out.write(bf,0,len);
                    }
                    //关流
                    out.close();
                    in.close();
                    System.out.println("该文件被保存了:"+fileName);
                    //删除temp文件夹里的文件
                    item.delete();
                    //表单项名字,和目录+随机名字,放到put里面
                    result.put(parameterName,new String[]{secondDir+uuidName});
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

UploadUtil

	/**
	 * 获取文件真实名称
	 * 由于浏览器的不同获取的名称可能为:c:/upload/1.jpg或者1.jpg 
	 * 最终获取的为  1.jpg
	 * @param name 上传上来的文件名称
	 * @return	真实名称
	 */
	public static String getRealName(String name){
		//获取最后一个"/"
		int index = name.lastIndexOf("\\");
		return name.substring(index+1);
	}
	
	
	/**
	 * 获取随机名称
	 * @param realName 真实名称
	 * @return uuid 随机名称
	 */
	public static String getUUIDName(String realName){
		//realname  可能是  1.jpg   也可能是  1
		//获取后缀名
		int index = realName.lastIndexOf(".");
		if(index==-1){
			return UUID.randomUUID().toString().replace("-", "").toUpperCase();
		}else{
			return UUID.randomUUID().toString().replace("-", "").toUpperCase()+realName.substring(index);
		}
	}
	
	public static String BaseDir(){

		ResourceBundle upload = ResourceBundle.getBundle("upload");
		return upload.getString("base");
	}



	/**
	 * 获取文件目录,可以获取256个随机目录
	 * @return 随机目录 /a/4  /b/c
	 */
	public static String randDir(){
		String s="0123456789ABCDEF";
		Random r = new Random();
		return "/"+s.charAt(r.nextInt(16))+"/"+s.charAt(r.nextInt(16))+"/";
	}

	public static void mustExist(String path){
		File file = new File(path);
		if (!file.exists()){
			file.mkdirs();
		}

	}

upload.properties

base=C:\\Users\\Admin\\Desktop\\upload1

3.Ajax上传文件的封装

代码实现

<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript" src="resources/js/jquery-1.11.3.min.js" ></script>
		<script type="text/javascript" src="resources/js/jquery-heima-0.0.1.js" ></script>
		<script>
			$(function(){
				
				$("#upload").click(function(){
					/*var params=$("form").serialize();
					alert(params)*/
					//js 专门提供一个对象 对付 ajax上传文件
					//这个对象构建的需要给传入参数
					//对应的form表单对象
					var fd=new FormData(document.getElementById("f01"));
					
					/*$.ajax({
						url:"http://api.itheima349.com/upload",
						data:fd,
						type:"post",
						contentType:false,//不要动手脚 对请求头 不要覆盖
						processData:false,
						success:function(data){
							alert(data);
						},
						error:function(){
							//...
						}
						
					})*/
					
					//封装好的方法直接用
					HM.ajaxFile("/upload","f01",function(vo){
						alert(vo)
						
					})
					
				})
			})
		</script>
	</head>
	<body>
		<form id="f01"   enctype="multipart/form-data" >
	        用户名:<input type="text" name="username"><br>
	        备注:<input type="text" name="desc"><br>
	        头像:<input type="file" name="avatar"><br>
	        身份证:<input type="file" name="IDCard"><br>
        	<input type="button" value="点我提交" id="upload">
    	</form>
	</body>
</html>

这两个参数一定要改为false,要不传不了值
在这里插入图片描述
在这里插入图片描述

4.完成上传文件操作

	  前端:
	        携带整个表单提交servlet
	        成功后跳转
	  后端:
	       把照片放到对应的目录,开始封装product数据,插入数据库,返回
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值