




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、-PAGE . z本科生毕业论文设计题目: 基于Java网页版聊天室的设计与实现 姓 名: 义旺学院: 理学院专业: 信息与计算科学 班级: 信科092 *: 23109223 指导教师:爱萍职称: 副教授 2013年 5月 27日农业大学教务处制目录 TOC o 1-3 h z u HYPERLINK l _Toc356330591摘要 将效劳器发送的查询请求及时响应,并将结果返回。3数据库设计3.1创立数据库和数据表根据需求分析,本毕业设计的聊天室需要3各表,分别是用户信息表,敏感词汇表和聊天消息表。数据表名数据表中文名称数据表用途User用户信息表保存用户的根本信息Sensitivity
2、敏感词汇表存储敏感词汇Information聊天消息表存储聊天消息3.2创立根本信息表用户信息表字段名字段描述数据类型可否为空UserName用户名文本主键Password密码文本非空Se*性别文本Age年龄数字敏感词汇表字段名称字段描述数据类型可否为空Word敏感字文本主键聊天消息表字段名称字段描述数据类型可否为空InformationID消息编号数字主键Sender消息发送者文本Receiver消息接收者文本InformationDate消息时间日期/时间ChatInformation聊天消息文本4关键技术和难点4.1监控用户在线状态在聊天室程序中需要实时监控用户在线状态,当用户非正常退出
3、时例如当用户没有单击退出聊天室按钮,也没有单击窗口的关闭按钮,而是直接将页面转向其他将该用户从用户列表中删除。可以应用Servlet中的(HttpBindingListener接口)2实现此效果,HttpBindingListener接口监听HTTP会话中的对象时不需要在web.*ml中设定监听。通过HttpBindingListener接口监控用户在线状态的具体步骤:编写用来保存在线用户和对在线用户进展具体操作的类UserInfo,在该类中主要包括返回外界使用的实例对象、添加用户、获取用户列表和移除用户的方法。UserInfo类的关键代码如下:/ 增加用户public boolean add
4、User(String user)3 if (user != null) this.vector.add(user);return true; return false;/ 获取用户列表public Vector getList() return vector;/ 移除用户public void removeUser(String user) if (user != null) vector.removeElement(user);创立UserListener类,主要实现valueBound(HttpSessionBindingEvent arg0)和valueUnbound(HttpSess
5、ionBindingEvent arg0)方法,用于监控Session中的对象变化情况。在该方法中,通过valueBound方法向控制台输出上线用户的信息,通过valueUnbound()8方法向控制台输出下线用户的信息。UserListener类的关键代码如下:/ 设置在线监听人员public void setUser(String user) this.user = user;/ 获取在线监听public String getUser()4 return this.user;/ 当Session有对象参加时执行的方法public void valueBound(HttpSessionBin
6、dingEvent arg0) System.out.println(上线用户: + this.user);/ 当Session有对象移除时执行的方法public void valueUnbound(HttpSessionBindingEvent arg0) System.out.println(下线用户: + this.user);if (user != ) container.removeUser(user);在聊天室的Servlet实现类的登录聊天室的longinRoom()方法中,首先获得登录用户名和UserInfo类的对象,然后Session的过期时间设置为10分钟,在将该用户添加到
7、UserInfo类的对象中,最后将UserListener对象绑定到Session中。关键代码如下:/获得登录用户名UserInfo user=UserInfo.getInstance();/获得UserInfo类的对象session.setMa*InactiveInterval(600);/设置Session的过期时间为10分钟UserListener ul=new UserListener();/创立UserListener的对象ul.setUser(username);/添加用户user.addUser(ul.getUser();/添加用户到UserInfo类的对象中session.se
8、tAttribute(user,ul)10;/将UserListener对象绑定到Session中上述的代码中,一定要将UserListener对象绑定到Session中,否则起不到监听的效果。4.2通过快捷键发送聊天消息使用过的QQ聊天软件的用户都知道,在通过QQ聊天时,编好聊天容后按下快捷键Ctrl+Enter即可发送聊天容,实现该功能只需要在聊天容的文本框的onKeyDown事件中判断当前按下的快捷键是否为Ctrl+Enter,如果是则调用自定义的send() 方法发送聊天容。关键代码如下:54.3实现私聊所谓私聊就是只有发言人和接收人可以看到该信息,其他用户不能看到该信息,这样可以保证
9、用户间的悄悄话不被其他用户所看到。在保存聊天信息的*ML文件中设置一个isprivate节点,用于记录聊天信息是否为私聊信息。isPrivate节点的值为true或false,值为true时表示是私聊信息,否则表示不是私聊信息。添加私聊信息在*ML文件中的显示代码如下:5wgh微笑着无语font color=>l和你说一件事呀?2013-3-15 15:51:41true当用户输入聊天信息并发送后,在接收聊天信息的Servlet中,将聊天信息保存在*ML文件中,包括是否为私聊信息的参数isPrivate。关键代码如下:Element isPrivateNode = new Element(
10、isPrivate).setTe*t(false);newNode.addContent(isPrivateNode);在显示输入容时,判断聊天容是否为私聊容,即isPrivate节点是否为true,如果是则只在发言人和接收人的窗口中输出该聊天信息,并且在前面参加标记容私人对话,关键代码如下:boolean isPrivate = Boolean.valueOf(item.getChildTe*t(isPrivate);if (isPrivate) /获取私聊容if (userName.equals(to)| userName.equals(from) messages += 私人对话+ fr
11、om+ + face+ 对+ to+ 说:+ content+ + sendTime + ;4.4滚屏显示在实现聊天时,为了让用户可以及时看到最新发言,需要对聊天容进展滚屏显示,同时为了让用户可以看到全部聊天容,还需要提供不滚屏显示的功能。实现滚屏显示时,可以分为整个窗口的滚动和页面中元素的滚动两种情况:对整个窗口的容进展滚动滚动整个窗口,即对滚动条进展定位,可以通过sroll()函数的语法如下:window.scroll(*,y)其中,参数*表示滚动条水平位置的坐标;参数y表示滚动条垂直位置的坐标。另外将滚动条置底,只要将y的值设置的大一些即可,关键代码如下:6function scroll
12、Window()this.scroll(0,75000);setInterval(scrollWindow(),1000);scrollWindow();11这样每隔1000毫秒执行一次该函数,就可以让滚动条永远置底了。对指定页面元素中的容进展滚动对指定页面元素中的容进展滚动可以通过scrollTop属性实现。scrollTop属性表示当前对象的顶点距离其最外层对象元素的距离。代码如下:object.scrollTop=distance;聊天室的容显示区中滚屏效果就是使用该属性来定位最新聊天容的。.1在页面的适宜位置添加一个标记用于显示聊天容。由于在现实聊天信息时默认情况下是滚屏显示,因此需要
13、将该层的overflow属性设置为hidden即隐藏,关键代码如下:聊天容.2添加一个用户控制是否滚屏的复选框,在该复选框的onClick事件上调用一个用于控制是否滚屏的方法checkScorllScreen()11,关键代码如下:.3编写一个自定义的JavaScript函数checkSrcollScreen()用于控制是否滚屏,在该方法中,首先判断添加的复选框是否为选中状态,如果不是则表示滚屏,否则将设置聊天容的标记的scrollTop属性等于它的滚动高度乘以2。checkSrcollScreen()函数的关键代码如下:function checkScrollScreen()63if(!fo
14、rm1.scrollScreen.checked)document.getElementById(content).style.overflow=scroll;elsedocument.getElementById(content).style.overflow=hidden;/当聊天信息超过一屏时,设置最先发送的聊天信息不显示document.getElementById(content).scrollTop= document.getElementById(content).scrollHeight*2;setTimeout(checkScrollScreen(),500);4.5自动踢出
15、长时间不发言的用户为了保证聊天室的搞笑运行,需要提供踢出长时间不发言用户的功能7。在实现踢出长时间不发言的用户时,可以通过采用JavaScript脚本的window对象的setTimeout()方法定时调用退出系统的函数实现。Window对象的setTimeout()方法用于延迟代码的执行,该方法的根本语法格式如下:window.setTimeout(code,delay);其中,code用于指定要延迟执行的代码通常为一个自定义的JavaScript函数;delay用于指定延迟时间以毫秒为单位。通过window对象的setTimeout()方法实现定时踢出指定用户的关键代码:Timer=win
16、dow.setTimeout(E*it(),);上述的代码实现了定时踢出长时间不发言的用户,如果想实现踢出长时间不发言的用户,还需要在用户发言后,将上述的计时器重新计时。关键代码如下:clearTimeout(timer);timer=window.setTimeout(E*it(),)9;注意在实现用户发言的方法中,一定要调用此方法,否则不会更新用户的发言时间,造成即使用户发言了还是被踢出了。4.6敏感词的自动屏蔽在以QQ聊天室为首的大多数聊天室都没有屏蔽敏感词汇功能,为了营造良好的网络文明用语环境,本聊天室特意增设此功能。用户进入聊天室就会看到有醒目的提醒,提醒大家文明聊天,不要说一些的敏
17、感的字眼。而一旦有用户说了敏感的字眼,系统就要自动屏蔽掉。 在效劳器数据库将那些敏感的字放进去,一旦用户聊天时,系统自动将用户的聊天的词语在数据库表中去查找,一旦有敏感的词,通过控制器Servlet的容过滤修改输出的的字符串,改为*。关键代码如下:for (String sensiti : sensities) int preInde*=-1;if(preInde* = infro.inde*Of(sensiti)!=-1)int lastInde* = preInde* + sensiti.length();updatedInfor=infro.substring(0,preInde*)+*
18、+infro.substring(lastInde*)8;5系统程序开发5.1用户模块当用户访问聊天室时,首先进入的是登录聊天室页面。如果用户没有账号,则可以点击页面的注册,进入到注册页面;如果用户之前已经登录过,则直接输入用户名、密码,进展登录。用户注册当用户进入到注册页面后,提示用户填写详细信息,点击注册按钮后,系统开场判断用户名、密码、确认密码、年龄和性别是否非法,判断用户名是否已经被注册,如果都能验证通过才允许用户注册成功。下面是注册界面和详细描述:.1设计注册聊天室页面,该页面用于新用户注册关键代码如下:9用户名: 密码: 确认密码: 年龄: 性别:男女 id=error $erro
19、r10已有账号,登录!.2设计聊天室的Servlet实现类,添加注册聊天室的方法registRoom。在该方法中,首先获得注册用户,然后判断用户名和密码是否已存在。关键代码如下:for (User user : users)if(user.getUsername().equals(username)request.getSession().setAttribute(error, 该用户名已存在!);response.sendRedirect(register.jsp);return ;User user2 = new User(username, password, se*, age);Str
20、ing userLine = user2.toString();us.add(user2);this.saveUser(userLine);.3编写注册成功页面regist_ok.jsp,在该文件中将页面重定向到聊天室的主界面。注册成功的关键代码如下:用户登录当用户单击登录按钮后,系统将判断用户名是否存在,密码是否和用户名搭配,用户是否已登录,如果都能验证通过才允许用户登录成功。下面是登录界面和详细描述:.1设计登录聊天室页面,该页面主要用于收集用户输入的登录信息,以及通过自定义的JavaScript函数验证输入信息是否为空,该页面的表单元素包括输入用户名、密码的文本框和登录提交表单的按钮,关
21、键代码如下:用户名:密码:11.2在聊天室的Servlet实现类中,添加登录聊天室的方法loginRoom(),在该方法中,首先获得登录用户,然后判断用户名是否存在、密码是否和用户名搭配、用户是否已登录。如果登录成功,将该用户添加到在线用户列表中,然后向向保存聊天信息的*ML文件中添加一条系统公告,最后将页面重定向到登录页面;否则返回到登陆界面,并给出相应的提示信息。关键代码如下:/获得登录用户名String username=su.toGBK(request.getParameter(username);Vector vector=user.getList();boolean flag=tr
22、ue;/标记是否登录的变量/判断用户是否登录if(vector!=null&vector.size()0)for(int i=0;ivector.size();i+)if(user.equals(vector.elementAt(i)PrintWriter out= response.getWriter();out.println(alert(该用户已经登录);window.location.href=inde*.jsp;);flag=false;break;/保存用户信息if(flag)UserListener ul=new UserListener();/创立UserListener的对象
23、ul.setUser(username); /添加用户/添加用户到UserInfo类的对象中user.addUser(ul.getUser()/将UserListener对象绑定到Session中session.setAttribute(user,ul);/保存当前登录的用户名session.setAttribute(username,username);/保存登录时间session.setAttribute(loginTime,new Date().toLocaleString();.3编写登录成功页面login_ok.jsp,在该文件中将页面重定向到聊天室的主界面。登录成功的关键代码如下:
24、125.2聊天室主体模块功能设计聊天室主页面在用户登录成功或者注册成功后即可进入聊天室的主界面,在该页面中包括页面头部、在线人员列表区、聊天容显示区和用户发言区4局部,布局如下:页面头部在线人员列表区聊天容显示区用户发言区聊天室主界面主要采用标签进展布局,关键代码如下: 在线人员列表 聊天容 实时获取并显示在线用户列表在开发聊天室程序时,为了让用户及时了解当前在线用户,并与其他用户进展交流,需要提供实时获取并显示在线人员列表的的功能。在聊天室的主界面中,左侧显示在线人员列表及在线人员。为了实时显示在线人员列表,本设计应用了Aja*技术。以下是实现获取并显示在线用户列表的界面和功能:.1编写自定
25、义的JavaScript函数showOnline(),用于实例化Aja*对象。showOnline()函数的关键代码如下:Function showOnline()Var loader=new net.Aja*Request(online.jspnocache=+new Date().getTime(),deal_online,onerror,GET)6;在上述的代码中,一定要有该行代码nocache=+new Date().getTime(),否则将出现在线成员列表不更新的情况。.2本设计中Aja*进展异步请求目标的URL地址为online.jsp,在该jsp文件中,主要是将保存在集合类中的
26、在线人员列表显示到页面。online.jsp页面的代码如下: 所有人 0)String username=; amount=vector.size();for(int i=0;i a href=# onclick=set() 当前在线人.3在聊天室的主界面中,将左侧用于显示在线人员列表的单元格的id属性设置为online,用于实时显示在线人员列表,关键代码如下:在线人员列表.4编写Aja*的回调函数deal_online(),用于将获取的在线人员列表赋值给id为online的标记的innerHTML属性。deal_online()函数的关键代码如下:Function deal_online()
27、online.innerHTML=this.req.responseTe*t;.5为了让页面载入后就调用Aja*获取在线人员列表,并且每隔10秒钟便获取一次数据,还需要在页面中添加JavaScript代码。关键代码如下:window.setInterval(showOnline();,10000);window.onload=function()showOnline();实现用户发言在聊天室程序中一个必不可少的功能就是实现用户发言,在本设计的聊天室中,用户发言区位于聊天室主界面的底部,以下是实现用户发言的界面和功能:.1在页面的适宜位置添加用于收集用户发言信息的表单及表单元素,关键代码如下:i
28、nput name=from value= 对 表情 无表情的说: 悄悄话滚屏 字体颜色: 默认颜色 红色热情在上面的代码中,语句用户显示当前的登录用户名。聊天对象文本框被设置为只读属性时用户就不能手动输入聊天对象,因此还需要提供选择聊天对象的功能,还可以通过在主页面中添加选择聊天对象的JavaScript自定义函数及在在线人员列表中添加实现。实现将选择的聊天对象添加到聊天对象文本框的JavaScript代码如下:function set(selectPerson)/自动添加聊天对象if(selectPerson!=)if(form1.isPrivate.checked & selectPer
29、son=所有人)alert(请选择私聊对象!);elseform1.to.value=selectPerson;elsealert(请重新选择聊天对象!);.2编写自定义的JavaScirpt函数send(),用于调用Aja*实现用户发言。在该函数中,首先验证输入信息的合法性,然后再将提交的表单元素的容连接为一个参数字符串,最后实例化Aja*对象。Send()函数的关键代码如下:if(form1.to.value=)alert(请选择聊天对象!);return false;if(form1.content1.value=)alert(发送信息不可以为空!);form1.content1.foc
30、us();return false;if(form1.isPrivate.checked)isPrivate=true;elseisPrivate=false;Varparam=+&color=+form1.color.value+&to=+form1.to.value+&content=+&isPrivate=+isPrivate; var loader=newnet.Aja*Request(MessagesActionaction=sendMessage,deal_send,onerror,POST,param)13;.3在聊天室相关的Servlet实现类中添加发送聊天信息的方法sendM
31、essages()。在该方法中,首先获取用户发言的相关信息。并对出现中文的信息进展转码,然后判断保存当天聊天信息的*ML文件是否存在,如果不存在则创立该文件,最后将聊天信息保存到*ML文件中,并重定向网页。sendMessages()方法的关键代码如下:channel.addContent(newNode); / 创立messages节点Element fromNode = new Element(from).setTe*t(from);newNode.addContent(fromNode);/添加发言人子节点Element faceNode = new Element(face).setT
32、e*t(face);newNode.addContent(faceNode);/添加表情子节点Element toNode = new Element(to).setTe*t(to);newNode.addContent(toNode);/添加接收者子节点Element contentNode = new Element(content).setTe*t( + content + );newNode.addContent(contentNode);/添加聊天容子节点Element sendTimeNode = new Element(sendTime).setTe*t(sendTime);ne
33、wNode.addContent(sendTimeNode);/添加发言时间子节点Element isPrivateNode = new Element(isPrivate).setTe*t(isPrivate);newNode.addContent(isPrivateNode);/添加是否为悄悄话子节点request.getRequestDispatcher(MessagesActionaction=getMessages&nocache=+ random.ne*tInt(10000).forward(request, response);*MLOutputter *ml = new *ML
34、Outputter(Format.getPrettyFormat();*ml.output(feedDoc, new FileOutputStream(fileURL);在上述的代码中调用了creatFile()方法,该方法用于根据当前日期生成*ML文件名并 判断该文件是否存在,如果不存在则创立该文件,关键关键代码代码如下:file.createNewFile(); / 创立文件String dataStr = rn;dataStr = dataStr + rn;dataStr = dataStr + ;dataStr = dataStr + rn;byte content = dataStr
35、.getBytes();FileOutputStream fout = new FileOutputStream(file);fout.write(content); / 将数据写入输出流return fileURL;实时显示聊天容在聊天室程序中另一个必不可少的功能就是实现显示聊天容。在本设计的聊天室中,聊天容显示区位于聊天室主界面的右侧。在实现显示聊天容是,为了实时显示聊天容,这里应用了Aja*技术。以下是实现显示聊天容的界面和功能:.1编写自定义的JavaScript函数showContent()用于实例化Aja*对象。showContent()函数的关键代码如下:Function sho
36、wOnline()13Varloader1=new net.Aja*Request(MessagesActionaction=getMessages&nocache= + new Date().getTime(),deal_online,onerror,GET)13;.2本设计中,Aja*进展异步请求目标的URL地址为MessagesActionaction=getMessages。从该URL地址可以看到,在进入主界面前会调用聊天室相关的Servlet实现类中的getMessages()8方法。在该方法中,首先判断保存当前聊天信息的*ML文件是否存在,如果不存在则创立它,然后开场解析保存聊天信
37、息的*ML文件,并将聊天容连接为一个字符串,最后将连接后的字符串保存到HttpServletRequest对象中,并重定向网页到输入聊天容的页面content.jsp。getMessages()方法关键代码如下:/获取发言人String from = item.getChildTe*t(from);/获取表情String face = item.getChildTe*t(face);/获取接收者String to = item.getChildTe*t(to);/获取发言容String content = item.getChildTe*t(content);boolean isPrivate
38、 = Boolean.valueOf(item.getChildTe*t(isPrivate)messages += + from+ + face+ 对 + to+ 说: + content+ + sendTime + ;/保存获取的聊天信息request.setAttribute(messages, messages);request.getRequestDispatcher(content.jsp).forward(request,response)14;.3编写显示聊天容的JSP页面,在该页面中只需要应用out对象的prinln()方法将返回的执行结果输出即可,关键代码如下:.4在聊天室
39、的主界面中,在右侧显示聊天容的单元格中添加一个id属性为content的标记,用于实时显示聊天容。关键代码如下:聊天容.5编写Aja*的回调函数deal_content(),在该函数中,首先获取Aja*处理页面的返回值,然后取出字符串的Unicode空白符,最后判断在获取信息时是否产生错误,如果是则退出聊天室,否则将获取的聊天容赋值给id为content的标记的innerHTML属性。deal_content()函数的关键代码如下:function deal_content()var returnValue=this.req.responseTe*t;/获取Aja*处理页的返回值var h=r
40、eturnValue.replace(/s/g,);/去除字符串中的Unicode空白符if(h=error)/alert(您的账户已经过期,请重新登录!);E*it();elsecontent.innerHTML=sysBBS+returnValue+;为了让页面载入后就使用Aja*获取聊天容,并且每隔1秒钟就便获取一次数据,还需要在页面中添加JavaScript代码。关键代码如下:window.setInterval(showContent();1000);window.oload=function()showContent();5.3退出聊天室模块退出聊天室包括平安退出和非平安退出,本设
41、计的聊天室对这两种退出都进展了处理,以保证聊天室系统的强健性。下面是两种退出聊天室的功能15模块:实现平安退出聊天室功能平安退出聊天室是指单击退出聊天室按钮时退出聊天室。实现平安退出聊天室的界面和功能如下:.1在主页面的适宜位置添加退出聊天室按钮,并在按钮的onclick事件中调用自定义的JavaScript函数E*it()关键代码如下:编写自定义的JavaScript函数E*it(),在该函数中首先将页面重定向到退出聊天室页面leave.jsp,然后再弹出欢送您下次光临!对话框,关键代码如下:Function E*it()window.location.href=leave.jsp;aler
42、t(欢送您下次光临);编写退出聊天室页面leave.jsp,在该页面,首先销毁Session然后将页面重定向到登陆页面。leave.jsp页面的完整代码如下:处理非正常退出聊天室非正常退出聊天室通常是指单击浏览器的关闭按钮退出聊天室。在实现单击关闭按钮退出聊天室时,只需要在聊天室的主界面中添加以下代码即可。window.onbeforeunload=function()if(event.clientYdocument.body.scrollWidth)E*it();6.总结通过这次的毕业设计,我不仅拓宽了自己的知识面,还在实践过程中稳固和加深了自己所学的理论知识,使自己的技术素质和实践能力有了进一步的提高,自己分析问题和解决问题的能力都得到了锻炼和提高,完善了自己的知识构造,加深了对计算机软件知识的理解16。这次毕业设计完成后,体会颇多,在学与做的过程中,取长补短,不断学习新的知识,吸取经历,到达进步的目的。在学与做的过程中自身的努力以及相关图书资料的帮助,逐渐熟悉了JSP和Aja*在java-web
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 年度计划中应该关注的关键指标
- 个人合作投资合同标准文本
- 两人合伙开家具店合同标准文本
- 上海社保合同标准文本
- 2025湖北省智能手机买卖合同(示范合同)
- 不锈钢花池合同标准文本
- 全国买卖合同标准文本
- 消防安全与保安人员的职责计划
- 保安总公司合同标准文本
- 2025光纤敷设项目合同
- 类医疗器械经营质量管理制度及工作程序
- 2025交管12123学法减分考试题库和答案
- T-JDFA 02-2024 江苏省转型融资主体认定评价标准
- 5共同建设有序生活(教学设计)-统编版道德与法治五年级上册
- 2025年新闻、记者采编人员岗位职业技能资格基础知识考试题库(附答案)
- 2025年吉林铁道职业技术学院单招职业技能测试题库一套
- 生物化学习题集(护理)
- 2025年化妆品包装标签法律要求培训
- 中间人协议书范本(2025年)
- 演员经纪合同法律风险-洞察分析
- 2024-2030年全球及中国石榴花提取物行业发展动态及供需前景预测报告
评论
0/150
提交评论