`

APICloud(四):图片上传-Java版

阅读更多

这一篇讲“将选择的图片上传到指定的服务器”。

说实话,这个功能写了好久,一会儿json拼的有问题访问不到后台,一会儿后台又说form表单的enctype不是multipart/form-data类型,各种乱七八糟的问题折腾了一下午都没好,第二天再弄的时候,竟然莫名其妙的好了,而且后来再也没出过问题。真是匪夷所思啊!

好啦,废话说到这里,言归正传。

这里以发布公告为例:输入公告内容,上传需要的图片(也可以不上传),点击“保存”按钮进行数据提交。其中内容能够和图片必须有一项不为空,“保存”按钮触发事件savaAnnounce()。

一、提交数据的代码如下:

/**
 *该方法用来保存公告
 * @param obj:A标签
 *  **/
function savaAnnounce(obj){
	//判断保存是灰色的还是绿色的,若是灰色的不能保存
	var opacity = $(obj).css("opacity");
	//当前按钮处于置灰状态,不能操作
	if((opacity+"")=="0.5") return false;
	
	//进行进度条提示	
	api.showProgress({
    	title: '数据提交中',
    	modal: false
	});
	
	//1、获取公告内容
	var announceContent = jQuery.trim($("#announceContent").val());//去除左右的空格
	var contentLen = announceContent.length;
	if(contentLen>0){//说明有填写内容,那么校验是否有特殊词汇,若是没有内容不校验		
		//判断是否有敏感词汇
		if(checkStr2(announceContent) || checkStr2(announceContent)){//两个当中有一个有特殊字符
			showErrorInfoBySys("内容不允许有特殊字符","1");
			return false;
		}
	}else{//说明没有数据
		announceContent = "";
	}
	
	//2、获取图片数量
	var picLen = $("#picList").children().length;
	
	//alert(contentLen+"\n"+picLen);
	//3、若是内容和图片数量都为0,说明什么都没有填写,那么不能提交数据
	if(contentLen<=0 && picLen<=0){
		showErrorInfoBySys("请输入内容或上传图片","1");
		return false;
	}
	
	//4、处理图片路径信息
	var fileList = "";
	if(picLen>0){
		$("#picList").children().each(function(i){		
			fileList+=",\"file"+(i+1)+"\":\""+this.children[0].src+"\"";//只显示文件名称
		});
		//截取掉最开始的逗号
		if(fileList.length>1){
			fileList = fileList.substring(1);
		}	
	}	
	fileList = eval('('+("{"+fileList+"}")+')');
	
	//4、提交数据	
	api.ajax({
	    url:$api.getStorage("url"),
	    method:'post',
	    dataType:'text',
	    data:{
	    	values:{
        		'announceContent':announceContent,
	        	'user_id':$api.getStorage("u_id"),
	        	'user_name':$api.getStorage("u_name"),
	        	'time':new Date().getTime()
	    	},	    	
	    	files:fileList
	    }
	},function(ret, err){
		api.hideProgress();//隐藏进度提示框		
	    if (ret) {
		     //跳转到公告列表界面:
		     api.openWin({
		          name: 'my_notice',
		          url: 'mynotice.html',
		          pageParam:{
		                'user_id':$api.getStorage("u_id")
		            },
		            progress:{
		            	type:"default",
		            	title:"玩命加载中..."
		            }
	            });
	    } else {
	        api.alert(JSON.stringify(err));
	    }    			    
	});	
}

/**
 *该方法用来显示错误信息-调用系统定时方法
 * @param flag:1-隐藏进度提示框 非1:不隐藏
 * @param msg:错误信息
 * **/
function showErrorInfoBySys(msg,flag){
	if((flag+"")=="1"){
		api.hideProgress();//隐藏进度提示框
	}
	//显示错误信息
	api.toast({
	    msg: msg,
	    duration: time,
	    location: 'bottom'
	});   		
}

/**该方法用来判断字符串中是否存在特殊字符-只包括SQL常用关键字
/*true:说明有特殊字符
/*false:说明没有特殊字符
 */
function checkStr2(str){
	var myReg = new RegExp("(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)");
	if(myReg.test(str)) return true; 
	return false; 
}

 二、后台进行文件上传

servlet

String retuStr="提交失败!";		
Object result = new com.wjl.dataengine.UploadFile().upload(request, response);
if(result instanceof SUser ){//如果是user的子类,说明添加成功
	//往数据库中添加日志
	addLog((SUser)result,"添加公告");
	retuStr="提交成功!";
}else{
	retuStr = result.toString();//否则就是错误信息
}
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Cache-Control", "no-store");
response.setDateHeader("Expires", 0);
System.out.println("retuStr:"+retuStr);
response.getWriter().write(retuStr);
response.getWriter().flush();
response.getWriter().close();

文件上传

/**
 * 该方法用来上传文件
 * @param request:request请求
 * @return Object:若是suer对象说明添加成功,否则返回错误信息
 * **/
public Object upload(HttpServletRequest request,final HttpServletResponse response){
	Object retuStr="提交失败!";	
//1、判断提交上来的数据是否是上传表单的数据
if(!ServletFileUpload.isMultipartContent(request)){//不是上传表单的数据
    //按照传统方式获取数据
	String announceContent = request.getParameter("announceContent");//公告内容
	String user_id = request.getParameter("user_id");//发布人序号
	String user_name = request.getParameter("user_name");//发布人
	System.out.println("内容:\n"+announceContent);
	/*
	try{
		String announceContent2 =URLDecoder.decode(announceContent,"utf-8");
		announceContent = announceContent2;
		System.out.println("转码之后的公告内容:"+announceContent);
	}catch(Exception e){
		e.printStackTrace();
	}
	*/
	if(announceContent==null || announceContent.trim().length()<=0){ 
		return "内容不能为空!";
	}else{
		result= new com.wjl.ServicesImpl().addAnnounce(announceContent,"",user_id,user_name);	
		if(result.trim().length()<=0){//说明添加成功了
			SUser user = new SUser();
			user.setS_user_id(Integer.parseInt(user_id));
			user.setS_username(user_name);
			return user;
		}else{//说明添加失败
			return retuStr;
		}
	}
}
//2、处理上传了文件的情况
//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
String savePath = getSavePath();
if(savePath.length()<=0){
	savePath = request.getRealPath("/")+"upload";
}
String year = com.wjl.Time.year().toString();//年份
String month = com.wjl.util.Time.month().toString();//月份
String day = com.wjl.util.Time.date().toString();//日
String tempPathForFile = year+File.separator+month+File.separator+day;
String filePath = "";
//上传时生成的临时文件保存目录
String tempPath = getTempPath();
if(tempPath.length()<=0){
	tempPath = request.getRealPath("/")+"temp";
}
File tmpFile = new File(tempPath);
if (!tmpFile.exists()) {
    //创建临时目录
    tmpFile.mkdir();
}                
try{
    //使用Apache文件上传组件处理文件上传步骤:
    //1、创建一个DiskFileItemFactory工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
    factory.setSizeThreshold(1024*100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
    //设置上传时生成的临时文件的保存目录
    factory.setRepository(tmpFile);
    
    //2、创建一个文件上传解析器
    ServletFileUpload upload = new ServletFileUpload(factory);
    //监听文件上传进度
    upload.setProgressListener(new ProgressListener(){
        public void update(long pBytesRead, long pContentLength, int arg2) {
            try {
            	float f = pBytesRead/pContentLength;
            	response.getWriter().write(f+"");
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        }
    });
    
     //解决上传文件名的中文乱码
    upload.setHeaderEncoding("UTF-8"); 
    
    
    //设置上传单个文件的大小的最大值,目前是设置为10*1024*1024字节,也就是10MB
    upload.setFileSizeMax(getFileBufferForSingle());
    
    //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为20MB
    upload.setSizeMax(getFileBufferFotTotal());
    //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
    List<FileItem> list = upload.parseRequest(request);
    
    //获取公告信息
    String announceContent = "";//公告内容
	String user_id = "";//发布人序号
	String user_name = "";//发布人
    StringBuffer imgInfo = new StringBuffer();//图片信息
    for(FileItem item : list){
        //如果fileitem中封装的是普通输入项的数据
        if(item.isFormField()){
            String name = item.getFieldName().trim();
            //解决普通输入项的数据的中文乱码问题
            String value = item.getString("UTF-8");
            if(value==null || value.trim().length()<=0)value="";
            else value = value.trim();
            //value = new String(value.getBytes("iso8859-1"),"UTF-8");
           //System.out.println("基础信息:\n"+name + "=" + value);
           //System.out.println("传过来的参数值:"+FieldType.getFileType(name));
           switch(FieldType.getFileType(name)){
           case ANNOUNCECONTENT:announceContent = value;break;
           case USER_ID:user_id = value;break;
           case USER_NAME:user_name = value;break;
           case TIME:break;
           default:break;
           }
        }else{//如果fileitem中封装的是上传文件
            //得到上传的文件名称,
            String filename = item.getName();
            if(filename==null || filename.trim().equals("")){
                continue;
            }
            //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
            //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
            filename = filename.substring(filename.lastIndexOf("\\")+1);
            //得到上传文件的扩展名
            //String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
            //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
            //System.out.println("上传的文件名称是:"+filename+"\n上传的文件的扩展名是:"+fileExtName);
            //获取item中的上传文件的输入流
            InputStream in = item.getInputStream();
            //得到文件保存的名称
            String saveFilename = makeFileName(filename);
            //得到文件的保存目录
            String realSavePath = makePath(saveFilename, tempPathForFile);
            //拼接图片路径用来保存到数据库
            imgInfo.append(","+File.separator+"bfp"+File.separator+realSavePath+File.separator+saveFilename);
            realSavePath = savePath+File.separator+realSavePath;
            System.out.println("文件目录:"+realSavePath);
            //File既可以代表文件也可以代表目录
   	     	File file = new File(realSavePath);
   	     	//如果目录不存在
   	     	if(!file.exists()){
   	     		//创建目录
   	     		file.mkdirs();
   	     	}
            //创建一个文件输出流
            FileOutputStream out = new FileOutputStream(realSavePath+File.separator+saveFilename);
            //创建一个缓冲区
            byte buffer[] = new byte[1024];
            //判断输入流中的数据是否已经读完的标识
            int len = 0;
            //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
            while((len=in.read(buffer))>0){
                //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
                out.write(buffer, 0, len);
            }
            //关闭输入流
            in.close();
            //关闭输出流
            out.close();
            //删除处理文件上传时生成的临时文件
          item.delete();
          //retuStr = "文件上传成功!";
        }
    }
    String img = "";
    if(imgInfo.length()>1){
    	img = imgInfo.substring(1);
    }else{img="''";}
    
    //往数据库中添加内容
    String result="";
   result= new com.wjl.ServicesImpl().addAnnounce(announceContent,img,user_id,user_name);
	if(result.trim().length()<=0){//说明添加成功了
		SUser user = new SUser();
		user.setS_user_id(Integer.parseInt(user_id));
		user.setS_username(user_name);
		return user;
	}else{//说明添加失败
		return retuStr;
	}
}catch (FileUploadBase.FileSizeLimitExceededException e) {
    e.printStackTrace();
    retuStr="单个文件超出最大值!!!";
}catch (FileUploadBase.SizeLimitExceededException e) {
    e.printStackTrace();
    retuStr="上传文件的总的大小超出限制的最大值!!!";
}catch (Exception e) {
	retuStr= "文件上传失败!";
        e.printStackTrace();
    }
    return retuStr;
 }

 上传代码中用到的一些工具类

//1、上传的各个参数所在类
public enum FieldType {
	//规定表单字段
	ANNOUNCECONTENT,USER_ID,USER_NAME,TIME;  
      
    //提供方法用来获取文件类型  
    public static FieldType getFileType(String fileType){  
        return valueOf(fileType.toUpperCase());  
    }  
}

//2、时间操作类:
public class Time {
	public static GregorianCalendar ggcalendar=new GregorianCalendar(Locale.CHINA);
/**
	 * 返回当前的年
	 * @return
	 */
	public static Integer year(){
		return ggcalendar.get(Calendar.YEAR);
	}
	/**
	 * 返回当前月份
	 * @return
	 */
	public static  Integer month(){
		return ggcalendar.get(Calendar.MONTH)+1;
	}
/**
	 * 返回当前是几号
	 * @return
	 */
	public static  Integer date(){
		return ggcalendar.get(Calendar.DATE);
	}
}

//3、文件操作代码
/**
 * @Method: makeFileName
 * @Description: 生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称
 * @param filename 文件的原始名称
 * @return uuid+"_"+文件的原始名称
 */ 
 private String makeFileName(String filename){  //2.jpg
     //为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
     return UUID.randomUUID().toString() + "_" + filename;
 }
 
 /**
  * 为防止一个目录下面出现太多文件,要使用hash算法打散存储
 * @Method: makePath
 * @Description: 
 * @param filename 文件名,要根据文件名生成存储目录
 * @param savePath 文件存储路径
 * @return 新的存储目录
 */ 
 private String makePath(String filename,String savePath){
     //得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址
     int hashcode = filename.hashCode();
     int dir1 = hashcode&0xf;  //0--15
     int dir2 = (hashcode&0xf0)>>4;  //0-15
     //构造新的保存目录
     String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
     return dir;
 }
 
/**
 * 该方法用来获取允许上传的文件总大小
 * **/
public long getFileBufferFotTotal(){
	long buffer = 200*1024*1024;//文件上传允许最大为200M
	String fileSize = com.wjl.util.WebAppConfig.app("businessFileSizeForTotal");
	if(fileSize!=null){//说明有设置值
		fileSize = fileSize.trim();
		//有设置值且是数字
		if(fileSize.length()>0 && com.wjl.util.Utils.isNumeric(fileSize)){
			buffer = Integer.parseInt(fileSize)*1024*1024;
		}
	}
	return buffer;
}

/**
 * 该方法用来获取允许上传的单个文件大小
 * @return long:配置文件中配置的数据*1024*1024,也就是总共多少M
 * **/
public long getFileBufferForSingle(){
	long buffer = 10*1024*1024;//文件上传允许最大为200M
	String fileSize = com.wjl.util.WebAppConfig.app("businessFileSize");
	if(fileSize!=null){//说明有设置值
		fileSize = fileSize.trim();
		//有设置值且是数字
		if(fileSize.length()>0 && com.wjl.util.Utils.isNumeric(fileSize)){
			buffer = Integer.parseInt(fileSize)*1024*1024;
		}
	}
	return buffer;
}

/**
 * 该方法用来获取文件保存的路径
 * */
public String getSavePath(){
	String savePath = com.wjl.util.WebAppConfig.app("businessFilePath");
	if(savePath!=null && savePath.trim().length()>0){
		savePath = savePath.trim();
	}else{
		savePath = "";
	}
	return savePath;
}

/**
 * 该方法用来获取文件临时保存的路径
 * */
public String getTempPath(){
	String savePath = com.wjl.util.WebAppConfig.app("businessFileTempPath");
	if(savePath!=null && savePath.trim().length()>0){
		savePath = savePath.trim();
	}else{
		savePath = "";
	}
	return savePath;
}

//4、读取配置文件的类:
public final class WebAppConfig { 
/** 
     * 私有构造方法,不能创建对象 
     */ 
    private WebAppConfig() { } 
	/***
	 * 
	 * @param key:properties文件中各个选项的name值
	 * @return String:与name值对应的value值
	 */
	public static String app(String key){
		String value=null;
        if(key!=null && key.trim().length()>0){
        	Properties prop = new Properties(); 
            //读取指定的文件
        	InputStream in = WebAppConfig.class.getResourceAsStream("/webApp.properties"); 
            try { 
                prop.load(in); 
                value = prop.getProperty(key).trim(); 
            } catch (IOException e) { 
                e.printStackTrace(); 
            }
        }
        return value;
    }
}

 

 

 

 

 

 

分享到:
评论

相关推荐

    apicloud 图片上传

    四、图片上传 选择图片后,使用`apicloud.file.uploadImage`上传图片到服务器。该方法需要一个参数对象,包含: - localId:本地图片的ID,由`chooseImage`返回。 - serverUrl:服务器接收图片的URL。 - name:上传...

    SpringBoot+Vue前后端分离学校教学管理系统

    使用JWT实现单点登录,图片和文档上传使用阿里的OSS对象存储,短信功能使用腾讯云的接口,聊天功能使用了WebSocket实现实时聊天,整合Quartz框架实现定时任务的发布,整合了redis存储验证码。本系统使用的技术均吻合...

    分布式电源接入配电网的技术挑战与解决方案:风光互补无功补偿及PSO优化

    内容概要:本文探讨了分布式电源(DG)接入配电网所带来的技术挑战及其解决方案。首先介绍了DG接入对配电网潮流分布和电压稳定性的影响,随后详细讨论了风光互补无功补偿技术的应用,旨在稳定电压和提高电能质量。接着,文章阐述了粒子群算法(PSO)在电气互联和故障点位定位中的应用,展示了其在优化电网拓扑结构和快速准确定位故障方面的优势。最后,通过Simulink建模和仿真实验,验证了所提出的方法和技术的有效性。 适合人群:从事电力系统研究、分布式电源集成、智能电网优化的专业人士,以及对相关技术感兴趣的工程技术人员。 使用场景及目标:适用于分布式电源接入配电网的设计与优化,特别是在解决电压波动、无功补偿不足和故障定位不准等问题时。目标是提升配电网的稳定性和效率,确保电力系统的可靠运行。 其他说明:文中提供了多个Matlab和Python代码示例,用于具体实现风光互补无功补偿、粒子群优化算法以及Simulink仿真模型,便于读者理解和实践。

    基于博途V15的1500系列PLC六层电梯SCL编程与梯形图实现

    内容概要:本文详细介绍了使用博途V15软件和1500系列PLC实现单部六层电梯控制系统的SCL编程方法及其梯形图实现。主要内容涵盖电梯的基本控制逻辑,如楼层升降、平层停靠、呼叫响应等。文中通过具体代码示例展示了如何定义关键变量、处理楼层呼叫信号、实现电梯运行和平层停靠逻辑。此外,还讨论了状态机的设计、方向决策算法以及开关门控制等重要环节。文章强调了SCL语言在处理复杂逻辑方面的优势,并对比了梯形图在故障诊断时的直观性。 适合人群:对工业自动化控制感兴趣的技术人员,尤其是熟悉西门子PLC编程的工程师。 使用场景及目标:适用于需要深入了解电梯控制系统编程原理和技术实现的人群。目标是帮助读者掌握SCL语言和梯形图在电梯控制中的应用,提高编程技能。 其他说明:文章提供了完整的代码片段和详细的解释,有助于读者理解和实践。同时提醒读者关注实际应用中的细节问题,如安全保护机制、信号防抖处理等。

    电力电子领域LLC谐振变换器的MATLAB/Simulink仿真及软开关实现

    内容概要:本文详细介绍了如何使用MATLAB/Simulink对全桥和半桥LLC谐振变换器进行仿真,涵盖驱动配置、谐振参数计算、软开关验证以及闭环控制等方面。首先,文章讲解了半桥LLC的基本配置,包括PWM生成、死区时间和谐振参数的设定。接着,讨论了全桥LLC的扩展及其相对于半桥的优势,如更宽的增益范围和更好的输入电压适应性。然后,深入探讨了软开关的验证方法,强调了ZVS(零电压开关)的重要性和实现方式。最后,介绍了闭环控制的设计思路,包括PID控制器的应用和参数调整技巧。 适合人群:从事电力电子设计的研究人员和技术工程师,尤其是那些希望深入了解LLC谐振变换器仿真和优化的人群。 使用场景及目标:适用于需要进行LLC谐振变换器仿真的项目,旨在帮助工程师掌握从基本配置到高级控制的完整流程,确保高效稳定的电源转换系统设计。 其他说明:文中提供了大量MATLAB代码片段,便于读者理解和实践。此外,还给出了许多实用的调试建议和注意事项,有助于避免常见错误并提高仿真成功率。

    居民健康监测系统 2025免费JAVA微信小程序毕设

    2025免费微信小程序毕业设计成品,包括源码+数据库+往届论文资料,附带启动教程和安装包。 启动教程:https://www.bilibili.com/video/BV1BfB2YYEnS 讲解视频:https://www.bilibili.com/video/BV1BVKMeZEYr 技术栈:Uniapp+Vue.js+SpringBoot+MySQL。 开发工具:Idea+VSCode+微信开发者工具。

    宿舍管理系统 2025免费JAVA微信小程序毕设

    2025免费微信小程序毕业设计成品,包括源码+数据库+往届论文资料,附带启动教程和安装包。 启动教程:https://www.bilibili.com/video/BV1BfB2YYEnS 讲解视频:https://www.bilibili.com/video/BV1BVKMeZEYr 技术栈:Uniapp+Vue.js+SpringBoot+MySQL。 开发工具:Idea+VSCode+微信开发者工具。

    电力系统中同步发电机短路与电弧仿真的关键技术及其实现

    内容概要:本文详细介绍了同步发电机短路仿真和电弧仿真的重要性及其具体实现方法。首先讨论了同步发电机短路仿真的核心基础——派克变换,展示了如何利用Python进行派克变换的代码实现,并解释了短路电流的计算方法,包括次暂态电流、暂态电流和稳态电流。接着,文章探讨了电弧仿真的物理特性和数学模型,特别是经典的Mayr电弧模型,并给出了Matlab代码示例。此外,还提到了电弧在不同环境条件下的特性研究,如气压、湿度等因素对电弧的影响。最后,文章强调了这两种仿真在电力系统动态分析中的应用场景,特别是在评估短路故障对发电机及周边设备的影响方面的作用。 适合人群:从事电力系统研究的专业人士、电气工程师、高校师生及相关领域的研究人员。 使用场景及目标:适用于需要深入了解同步发电机短路和电弧仿真原理的研究人员和技术人员,旨在提高电力系统的安全性、可靠性,优化保护措施的设计。 其他说明:文中不仅提供了理论知识,还附带了具体的代码实现,便于读者理解和实践。同时,文章指出了仿真过程中可能出现的问题及解决方案,如数值稳定性问题和接口时序处理等。

    学生选课系统 2025免费JAVA微信小程序毕设

    2025免费微信小程序毕业设计成品,包括源码+数据库+往届论文资料,附带启动教程和安装包。 启动教程:https://www.bilibili.com/video/BV1BfB2YYEnS 讲解视频:https://www.bilibili.com/video/BV1BVKMeZEYr 技术栈:Uniapp+Vue.js+SpringBoot+MySQL。 开发工具:Idea+VSCode+微信开发者工具。

    基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明

    基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明,个人经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做大作业的学生和需要项目实战练习的学习者,可作为毕业设计、课程设计、期末大作业。 基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模拟浏览器行为的小红书关键词搜索和笔记爬取源码+文档说明基于Selenium模

    医笙小程序系统 2025免费JAVA微信小程序毕设

    2025免费微信小程序毕业设计成品,包括源码+数据库+往届论文资料,附带启动教程和安装包。 启动教程:https://www.bilibili.com/video/BV1BfB2YYEnS 讲解视频:https://www.bilibili.com/video/BV1BVKMeZEYr 技术栈:Uniapp+Vue.js+SpringBoot+MySQL。 开发工具:Idea+VSCode+微信开发者工具。

    工业自动化中高速追剪飞锯系统的维伦通触摸屏与台达PLC程序解析

    内容概要:本文深入探讨了高速追剪飞锯系统的实现细节,特别是维伦通触摸屏和台达PLC之间的协同工作。触摸屏作为人机交互界面,允许操作员设置如切割长度、运行速度等参数,并通过与PLC寄存器的关联实现数据传输。台达PLC则负责执行复杂的电子凸轮追剪算法,确保切割过程的高精度和稳定性。文中还介绍了关键的PLC指令,如MC_GearIn和CAM_GEN,以及它们在速度同步和位置控制中的应用。此外,文章揭示了一些调试技巧和潜在问题,如数据类型对齐、补偿算法和参数调整方法。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些对PLC编程和人机界面设计感兴趣的人。 使用场景及目标:适用于需要理解和优化高速追剪飞锯系统的场合,旨在提高生产效率和产品质量。通过学习本文,读者可以掌握如何设置和调试此类系统,从而减少故障率并提升性能。 其他说明:文章不仅提供了理论知识,还包括了许多实用的操作建议和经验分享,有助于读者更好地应对实际工作中遇到的技术挑战。

    高速永磁同步电机Maxwell仿真:50000-100000rpm转速区间的电磁与机械设计挑战

    内容概要:本文详细探讨了高速永磁同步电机(HSPMSM)在50000-100000rpm转速范围内的设计与仿真挑战。首先介绍了高速电机的应用背景及其面临的离心力和电磁损耗等问题。接着,通过具体实例展示了如何利用Maxwell软件进行电机的几何建模、材料设置、边界条件与激励设置,并进行了详细的模拟结果分析。文中特别强调了在极端转速条件下,如10万转时,电机内部的物理现象以及相应的优化措施,如采用碳纤维护套增强机械强度、调整损耗计算模型以提高精度等。 适合人群:从事电机设计与仿真的工程师和技术研究人员,尤其是对高速永磁同步电机感兴趣的从业者。 使用场景及目标:适用于希望深入了解高速永磁同步电机设计原理及仿真技巧的人群,旨在帮助他们掌握Maxwell软件的具体应用方法,解决实际工程中遇到的技术难题,如高转速下的电磁兼容性和机械可靠性问题。 其他说明:文章不仅提供了理论指导,还包括大量实用的操作步骤和代码示例,有助于读者快速上手并应用于实际工作中。此外,文中提到的一些特殊处理方式(如碳纤维护套的应用),为解决特定工况下的技术瓶颈提供了新思路。

    浪潮英信服务器 SA5212M5 用户手册

    浪潮英信服务器 SA5212M5 用户手册

    COMSOL仿真中放电电极击穿空气的电场分布与击穿电压计算

    内容概要:本文详细介绍了如何使用COMSOL进行放电电极击穿空气的仿真。首先构建了一个针尖电极和球头圆柱电极组成的模型,设置了静电和电流耦合的物理场,并进行了网格优化。通过参数化扫描和MATLAB脚本,计算不同间隙距离下的击穿电压,并利用Paschen曲线进行验证。同时探讨了电场强度在尖端的集中现象及其对击穿的影响,提出了改进网格质量和求解器设置的方法。最后,通过电场矢量图和电势分布图展示了仿真的结果。 适合人群:从事电磁场仿真、电气工程、等离子体物理等相关领域的研究人员和技术人员。 使用场景及目标:适用于需要精确计算电极间击穿电压和电场分布的研究项目,帮助设计高压设备和评估电极结构的安全性和可靠性。 其他说明:文中提供了详细的建模步骤和代码片段,便于读者复现实验结果。同时强调了网格质量、边界条件和求解器设置对仿真准确性的重要影响。

    家居项目后端资源采用ssm架构

    家居项目后端资源采用ssm架构

    互联网大厂面试题合集:并发编程面试题-重点.pdf

    整理一线大厂面试题合集

    牵牛花铅笔素材儿童教学课件模板.pptx

    牵牛花铅笔素材儿童教学课件模板

    我的日记 2025/4/19

    2024年的记录。

    互联网大厂面试题合集:Linux操作系统面试题.pdf

    整理一线大厂面试题合集

Global site tag (gtag.js) - Google Analytics