求解答XML二级建造师复习题集(3)

求详细讲解sax解析xml的原理,看不懂书上的。。_java吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:229,040贴子:
求详细讲解sax解析xml的原理,看不懂书上的。。收藏
&?xml version = "1.0" encoding="UTF-8"?&&students&&student&&name&张三&/name&&gender&男&/gender&&age&19&/age&&/student&&student&&name&李四&/name&&gender&女&/gender&&age&18&/age&&/student&&student&&name&王五&/name&&gender&男&/gender&&age&20&/age&&/student&&student&&name&金六&/name&&gender&女&/gender&&age&22&/age&&/student&&/students&import java.util.ArrayLimport org.xml.sax.Aimport org.xml.sax.SAXEimport org.xml.sax.helpers.DefaultHpublic class MySaxHandler extends DefaultHandler {ArrayList&Student& students = new ArrayList&Student&();private Sprivate Sprivate S@Overridepublic void startDocument() throws SAXException {
}@Overridepublic void endDocument() throws SAXException {System.out.println(students);}@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {tag = qN}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if("student".equals(qName)){Student student = new Student(name, gender, age);students.add(student);}tag="";}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if("name".equals(tag)){name = new String(ch, start, length);}else if("gender".equals(tag)){gender = new String(ch, start, length);}else if("age".equals(tag)){age = Integer.parseInt(new String(ch, start, length));}}}import java.util.ArrayLimport org.xml.sax.Aimport org.xml.sax.SAXEimport org.xml.sax.helpers.DefaultHpublic class MySaxHandler extends DefaultHandler {ArrayList&Student& students = new ArrayList&Student&();private Sprivate Sprivate S@Overridepublic void startDocument() throws SAXException {}@Overridepublic void endDocument() throws SAXException {System.out.println(students);}@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {tag = qN}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if("student".equals(qName)){Student student = new Student(name, gender, age);students.add(student);}tag="";}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if("name".equals(tag)){name = new String(ch, start, length);}else if("gender".equals(tag)){gender = new String(ch, start, length);}else if("age".equals(tag)){age = Integer.parseInt(new String(ch, start, length));}}}import java.io.Fimport java.io.IOEimport javax.xml.parsers.ParserConfigurationEimport javax.xml.parsers.SAXPimport javax.xml.parsers.SAXParserFimport org.xml.sax.SAXEpublic class SAXParserXML {public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {SAXParserFactory spf = SAXParserFactory.newInstance();SAXParser sp = spf.newSAXParser();sp.parse(new File("students.xml"), new MySaxHandler());}}
startElement这个函数开始读取的节点是&student&,endElement读取的是&/student&对不?之后tag="";为什么要这样写,再后来characters中的几个判断语句是什么意思?
大家帮我解答
新人表示完全看不懂
结束之后当然要清空啊太长,头晕
--------------------------魔兽老了还是我们都已长大了。。。如今我们这样子各奔前程的拼搏着,那段燃烧的岁月是否还记得?
1, 首先我们要知道什么是
解析?sax解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会对文档进行操作。(通俗的来说,它会从你 xml 文档一行一行的读取,不能后退, 当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件, 比如文档的开头和结束、元素开头和结束、以及元素中的字符数据等事件。 当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件)!2, SAX 解析的流程:// 1,创建解析工厂。SAXParserFactory factory = SAXParserFactory.newInstance();// 2,得到解析器。SAXParser sp = factory.newSAXParser();// 3,得到读取器。XMLReader reader = sp.getXMLReader();// 4,设置内容处理器。reader.setContentHandler("这里由程序员自己编写解析对象");//你传入的是 new MySaxHandler()。// 5,读取 xml 文档内容。reader.parse("src/...xml文件地址");3,现在来分析你的问题:(1),你的代码可以把多余你没用到的事件方法删除,然后在按照下面的思路整理你的代码格式:主标签
子标签头1标签体
子标签1结束主标签结束//上面也是 sax 一行一行解析你 xml 标签数据的执行顺序。(2),排序后的代码格式如下:public class MySaxHandler extends DefaultHandler {ArrayList&Student& students = new ArrayList&Student&();private Sprivate Sprivate S@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {//当读到开始标签的时候,就把tag属性置为标签名。 tag = qN}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {//接收到标签内容数据的通知, 如果是name元素则得到if("name".equals(tag)){name = new String(ch, start, length);}else if("gender".equals(tag)){gender = new String(ch, start, length);}else if("age".equals(tag)){age = Integer.parseInt(new String(ch, start, length));}}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {
//当到达一个标签的结尾,就看看标签名是不是student!
//如果是: 则存入该类文虎的name,gender,age,并封装成Student对象
//到集合if("student".equals(qName)){Student student = new Student(name, gender, age);students.add(student);}tag="";
//每次赋值后要将tag重置。}@Overridepublic void endDocument() throws SAXException {//读完xml文档的时候,打印集合。System.out.println(students);}}// startElement 方法是读取到开始标签的时候执行的操作。
characters
方法是读取到标签内容的操作。
endElement
方法是读取到标签结束时候的操作。
endDocument
方法是当读取完 xml 文件时的操作。
----------------------------------------------------3,解释你的程序: 你要跟着你解析的那个 xml 文件去看就可以懂了。startElement : 用tag变量记录读到的标签名characters
: 判断标签名是不是 name 字符串?如果是则将 name属性赋值为,name标签的内容。
else if 下面的同理。endElement
: 当读取到结束标签,判断结束标签名是不是 student ,如果是,那么注意:
这个时候的 name , gender,age 是不是都赋值了对吧? ok!!
然后用该三个属性构造出一个 student 对象存入集合。
并且将 tag 重置为 ""字符串!(因为方便下次循环读取对吧!endDocument
: 当整个解析 xml 文档完成,就打印最后的集合。
//如果文档没有解析完成,继续重复以上动作, endDocument 方法是不会触发的。4,总结你这段代码的目的: 读取 student.xml 文档的数据,并封装成 student 对象并存入ArrayList集合。5, 一道智力题解释 xml 文档 sax 解析方式的原理:有一栋楼,12 层。每一层都有一颗夜明珠。你从第一层开始做电梯,可以从第一层往上一直升。但是要求: 你要选中12层中最大的一颗夜明珠,否则你就得跳楼。//答案: 从第一层做到12层,用变量记住最大的那一颗夜明珠在那一层,然后到12层之后,在告诉它最大的夜明珠是那一层。6,总结以及参考资料。建议去看看参考资料:
把思绪抽空,走一遍下面:1,什么是 sax 解析 xml ? 不过就是用一种叫做 sax 的方式来读取 xml 文件的结构化数据是吧?没有疑问吧?2,sax解析它是不是 从第一行开始,一行一行往下面拿标签是吧?如: &ss&
&name&标签体 &/name&
第四行 &/ss&
第五行//针对以上解析开始: 运行到第一行: sax 发现 ss 头标签,(这个时候对应的读取到头标签的方法触发:startElement)提示:startElement 方法中是不是有三个参数阿? 执行到这里意思是 :sax 发现了一个头标签 ss ,startElement 方法触发,并给了你三个参数,其中 qName 参数就是给你该被触发头标签的名字:ss!! tag =qName 等同于
tag =其它同理, 懂了吧??注意: 如果你 startElement 方法中什么也不干,是不是也可以阿?假如我就不想获取头标签的信息,我就不在 startElement 方法中操作什么阿,对吧。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或xml字符串解析成Document疏失,求指导_【转载】 Struts学习之Message Resources配备详解_以邮件形式找回密码(VM模板)__脚本百事通
稍等,加载中……
^_^请注意,有可能下面的2篇文章才是您想要的内容:
xml字符串解析成Document疏失,求指导
【转载】 Struts学习之Message Resources配备详解
以邮件形式找回密码(VM模板)
xml字符串解析成Document疏失,求指导
xml字符串解析成Document出错,求指导我从别人的接口获取了一个xml的字符串,我需要对其进行处理,所以把这个字符串解析成Document。如下:
方法一:DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document allDoc = (Document) factory.newDocumentBuilder().parse(new ByteArrayInputStream(allField.getBytes()));
方法二:Document allDoc = new SAXReader().read(new ByteArrayInputStream(allField.getBytes()));
用的dom4j包,上面两种解析方式都出异常,如下:
异常一:[Fatal Error] :1:40: Content is not allowed in prolog.org.xml.sax.SAXParseException: Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:249)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)
at com.huawei.vbs.webservice.TMSSTest.getDoc(TMSSTest.java:29)
at com.huawei.vbs.webservice.TMSSTest.main(TMSSTest.java:41)
异常二:org.dom4j.DocumentException: Error on line 1 of document
: Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.dom4j.io.SAXReader.read(SAXReader.java:343)
at com.huawei.vbs.webservice.TMSSTest.getDoc(TMSSTest.java:30)
at com.huawei.vbs.webservice.TMSSTest.main(TMSSTest.java:41)
Nested exception: org.xml.sax.SAXParseException: Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1039)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at org.dom4j.io.SAXReader.read(SAXReader.java:465)
at org.dom4j.io.SAXReader.read(SAXReader.java:343)
at com.huawei.vbs.webservice.TMSSTest.getDoc(TMSSTest.java:30)
at com.huawei.vbs.webservice.TMSSTest.main(TMSSTest.java:41)
Nested exception: org.xml.sax.SAXParseException: Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1039)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at org.dom4j.io.SAXReader.read(SAXReader.java:465)
at org.dom4j.io.SAXReader.read(SAXReader.java:343)
at com.huawei.vbs.webservice.TMSSTest.getDoc(TMSSTest.java:30)
at com.huawei.vbs.webservice.TMSSTest.main(TMSSTest.java:41)
------解决方案--------------------1.xml文件编码不正确,java解析出现乱码
2.xml中有非法字符
【转载】 Struts学习之Message Resources配备详解
【转载】 Struts学习之Message Resources配置详解一、概述类MessageResources可以使开发者方便地支持多语言,包括支持多时间格式和数字格式。使用资源包的另一个好处是允许开发者将标签字符串集中存储在一个位置,而不是分散在不同的JSP页面里。例如,对于每个用户的名字的标签"First Name" ,我们可以将它写在资源包中,在适当的地方通过Struts标签简单的进行引用: &bean:write key="label.first.name"/&这样做将会让你对程序的更改变的简单容易,你不必在每一个JSP页面里更改标签的内容了。 二、用法使用消息资源包需要你做下面的事情:1. 为你想要支持的地方创建一个消息资源包。2. 配置WEB应用,加载消息资源包。3. 使用相应的JSP标签加载资源或者...4. ...在一个Action类中加载资源。 三、创建资源包MessageResources 类的默认的实现是一个包含"key=value" 对的文件,下面的一个消息资源包文件的例子。 label.username=Usernamelabel.password=Passwordlabel.first.name=First Namelabel.last.name=Last Namelabel.email=Email Addresslabel.phone.number=Phone Numberlabel.welcome=Welcome back {0} {1}!error.min.length=The input must be at least {0} characters in length.error.max.length=The input cannot be longer than {0} characters in length.大括号包围的整数是对java.text.MessageFormat 类的支持,程序员可以向value字符串中传递参数,对每个value字符串你最多可以传递4个参数。四、配置有两种途径通知Struts你的资源包的位置:web.xml 文件或者struts-config.xml 文件。首先来看web.xml 文件的配置: &servlet&&servlet-name&action&/servlet-name&&servlet-class&
org.apache.struts.action.ActionServlet&/servlet-class&&init-param&&param-name&
application&/param-name&&param-value&
com.systemmobile.example.ApplicationResources&/param-value&&/init-param&&/servlet&这个配置说明你的资源包的名字是ApplicationResources.properties,它位于com.systemmobile.example 包中。后缀".properties" 是隐含的,你不必显式地写出来。如果你还有另一个资源文件在相同的包中,例如ApplicationResources_fr.properties ,用来支持法语,你只需要象上面定义的那样列出文件名字即可。 定义资源文件的第二中方法(上面已经提到),是在struts-config.xml 文件中配置: &message-resources parameter="com.systemmobile.example.ApplicationResources"/&属性parameter 是必须的。和在web.xml文件中配置一样, 需要注意的是文件在包中的位置。 使用struts-config.xml 文件来配置消息资源文件是推荐的做法,因为它更有可扩展性,更灵活。 l
你可以使用message-resources 标签从不同的资源文件取不同的消息,前提是在配置的时候为不同的资源文件给出不同的key 属性的值。例如:&message-resources key="myResources" parameter="com.systemmobile.example.ApplicationResources"/&&message-resources key="moreResources" parameter="com.systemmobile.example.MoreApplicationResources"/&然后你必须这样使用bean:message 标签:&bean:message bundle="moreResources" key="some.message.key"/&l
设置属性null 的值为"false" 后,如果某个资源字符串不存在将返回???key??? 而不是仅仅显示null。这样很容易在JSP页面中看到你没有定义的资源,使得内部测试的速度更快。(关于如何从资源文件中获得消息的详细内容参见国际化 一节)&message-resources parameter="com.systemmobile.example.ApplicationResources" null="false"/&l
另外,message-resources 标签允许你使用自己实现的MessageResourcesFactory 接口,这不在本文的讨论范围。五、资源文件放在哪里关于资源文件最常见的问题是将资源文件放在WAR文件的哪里。简单的回答是该文件必须放在你的classpath下面,这意味着将资源文件放在一个JAR 文件中,或者放在/WEB-INF/classes 目录极其子目录下。下表给出了资源文件的位置,在message-resources 标签中"parameter" 属性的值以及简短的说明。 Resources Location parameter Value Description /WEB-INF/classes/ApplicationResources.properties ApplicationResources 文件放在classes 目录下, 该目录在web应用的classpath中. /WEB-INF/classes/resources/ApplicationResources.properties resources.ApplicationResources 该文件放在"resources" 目录下, 所以包名也就是路径名要给出。 In the app.jar file, in the com.systemmobile.example package/directory. com.systemmobile.example.ApplicationResources 文件在JAR文件中的全路径。
六、Tags最常用Struts 标签是bean:message 标签。使用这个标签的"key" 可以从资源文件中读特定的消息资源。你还可以传入四个参数中的一个或全部: &bean:message key="label.password"/&&bean:message key="error.min.length" arg0="6"/&&bean:message key="label.welcome" arg0="Ralph" arg1="Nader"/&html:message 可以让你向用户显示错误信息(默认)或消息信息,而html:errors 只显示错误信息。很明显,错误信息或消息信息一定要保存在request里,否则就什么也不会显示。这里有一个显示消息信息的例子: &logic:messagesPresent message="true"&
&html:messages id="msg" message="true"&
&div class="success"&
&bean:write name="msg"/&
&/div&&br/&
&/html:messages&&/logic:messagesPresent&还有一些标签也有限地支持消息资源,比如html:link。html:link标签通过定义"titleKey" 属性来显示标题文本。许多html 使用 "altKey" 属性从资源文件里获得alternate(替代)文本。七、Actions你还可以在Action 类中使用消息资源文件。Action 类有两个方法得到一个MessageResource 类的实例: // 返回一个request里的资源文件protected MessageResources getResources(HttpServletRequest request);// 返回一个request里的资源文件,// 该资源文件的标志上&message-resources/& 元素的内容protected MessageResources getResources(javax.servlet.http.HttpServletRequest request, java.lang.String key);MessageResources类可以让你从资源文件中得到本地化的消息。The API for MessageResources 可以在资源中找到。比较常用的方法有: // these methods load a resources key for the given localepublic String getMessage(java.util.Locale locale, java.lang.String key);public String getMessage(java.util.Locale locale, java.lang.String key,
java.lang.Object arg0);public String getMessage(java.util.Locale locale, java.lang.String key,
java.lang.Object[] args);public String getMessage(java.util.Locale locale, java.lang.String key,
java.lang.Object arg0, java.lang.Object arg1)public String getMessage(java.util.Locale locale, java.lang.String key,
java.lang.Object arg0, java.lang.Object arg1, java.lang.Object arg2);public String getMessage(java.util.Locale locale, java.lang.String key, java.lang.Object arg0,
java.lang.Object arg1, java.lang.Object arg2, java.lang.Object arg3);// these methods load a resources key for the locale retrieved// from the HttpServletRequestpublic String getMessage(java.lang.String key);public String getMessage(java.lang.String key, java.lang.Object arg0);public String getMessage(java.lang.String key, java.lang.Object[] args);public String getMessage(java.lang.String key, java.lang.Object arg0,
java.lang.Object arg1);public String getMessage(java.lang.String key, java.lang.Object arg0,
java.lang.Object arg1, java.lang.Object arg2);public String getMessage(java.lang.String key, java.lang.Object arg0,
java.lang.Object arg1, java.lang.Object arg2, java.lang.Object arg3);这些返回的字符串可以被设置成request 或 session 的参数并串会表现层。你可能注意到了一些重载方法getMessage(...) 选择了参数Object,而另外一些采用了参数arg0...arg3。这和 bean:message arg0...arg3 属性等价。 除了MessageResources 类,还有一些类使用了资源文件。ActionMessage类被用来从action 向JSP之间传递消息资源中的keys 。消息被用来作为bean 的属性。ActionError, ActionMessage的子类,使用消息资源中的keys 存储验证失败后的错误信息。八、国际化从资源文件中提取一个本地化信息可以由类MessageResources 来处理,或者由它的直接子类PropertyMessageResources类处理。既然类PropertyMessageResources 等经常地被用到,那么我们就来看看它是怎样使用getMessage(Locale, String) 方法来从资源文件中读取消息的。 举例说明:1. 如果你在ApplicationResources_pt_br.properties (Brazilian Portuguese)中没有发现消息的定义,系统将在ApplicationResources_pt.properties 文件中找,如果ApplicationResources_pt.properties 文件不存在或者也没有该消息,那就去ApplicationResources.properties 文件里查找了。2. 如果消息找到了,它就被加到本地化的缓存中并返回java.lang.String型数据。3. 如果消息没有找到,此时如果returnNull 属性被为默认的true,将返回 null。 否则将返回类似 ???key??? 的字符串,key 就是那个被传递的参数。 九、JSTLJSTL (JavaServer Pages Standard Tag Library) 的fmt标签最近开始流行起来,用来向JSP中显示资源文件的信息。它能很好地和Struts结合在一起。使用它非常简单,只要下载JSTL 的jar 文件和TLDs 并把它们拷贝到你的应用的正确的位置,然后在web.xml文件中加入下面的内容: &context-param&
&param-name&javax.servlet.jsp.jstl.fmt.localizationContext&/param-name&
&param-value&ApplicationResources&/param-value&&/context-param&上面的配置是假定你的ApplicationResources.properties文件是放在/WEB-INF/classes 目录下的。 参见above 更多情况。 然后将这个标签库直接放在你的JSP中: &%@ taglib prefix="fmt" uri="/jstl/fmt" %&最后,下面的标签将显示资源文件的内容: &fmt:message key="label.first.name"/&还有一个使用fmt 标签获得资源的例子。(注意: 该段程序取自Jakarta JSTL examples。) // loading a resource from a specific bundle and populating a parameter&fmt:message key="currentTime" bundle="${deBundle}"& &fmt:param value="${currentDateString}"/&&/fmt:message&// using the forEach iterator to populate paramters&fmt:message key="serverInfo" bundle="${deBundle}"& &c:forEach var="arg" items="${serverInfoArgs}"&
&fmt:param value="${arg}"/& &/c:forEach&&/fmt:message&十、结论在向JSP文件方便地传递消息的同时,Struts使用消息资源文件还帮助我们创建国际化的Web应用。我们既可以使用正在快速发展中的JSTL标签,也可以使用Struts标签,或直接在action中得到一条具体的消息。我希望这篇文章为您阐明了一些Struts中常用的但有时会混淆的东西。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zerowzj/archive//2342569.aspx
根目录下建文件夹,将messages-default.properties放入,右键点击工程属性,在source中添加resource文件夹,这样保证resource文件夹编译后在web-inf/classes下。
在struts.xml中添加&message-resources parameter="com.messages-default"/&
以邮件形式找回密码(VM模板)
以邮件方式找回密码(VM模板)
每个网站都有安全中心,而安全中心又都有找回密码,找回密码又必然会出现 以邮件方式找回。
分析: 当用户以邮件方式找回密码时,分为3步骤:
1:验证用户名是否存在,
2:验证用户所填写的邮箱是否与用户的用户名匹配,
3:生成一个被加密后的超链接,此链接最好设上有效期,这个链接也采用行之有效的算法。
4:把生成后的链接发到用户邮箱上
5:当用户收到邮件并点此链接时,直接跳到修改密码的页面。
在此,我给大家贴一个找回邮件的详细代码,发送邮件的模板引擎为 vm。
长话短说,下面我说具体代码步骤.
* 读取邮件模板
* @param data
private static String emailTemplate(Map&String, String& data,String filePath) {
String result =
VelocityEngine velocity = new VelocityEngine();
Properties properties = new Properties();
properties.setProperty("resource.loader", "class");
properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
velocity.init(properties);
Template t = velocity.getTemplate(filePath, "utf-8");
VelocityContext context = new VelocityContext();
for (Map.Entry&String, String& entry : data.entrySet()) {
context.put(entry.getKey(), entry.getValue());
StringWriter writer = new StringWriter();
t.merge(context, writer);
result = writer.toString();
writer.close();
} catch (Exception e1) {
e1.printStackTrace();
* 发送密码到邮箱
* @param user
* @param password
* @param email
收密码的邮箱号码
public static void sendEmail(UserDTO userDTO,String password,String email){
InputStream in =
in = WebUtil.class.getResourceAsStream("/mail.properties");
Properties p = new Properties();
if (in != null) {
p.load(in);
String authuser=p.getProperty("mail.username");
//发送人用户名
String authpwd= p.getProperty("mail.password");
//邮箱密码
String host = p.getProperty("mail.host");
//smtp服务器名字
String port = p.getProperty("mail.port");
String from = p.getProperty("mail.from");
//来自哪里
String title = p.getProperty("uc.title");
//邮件标题,替换发送的邮箱名字
String url = p.getProperty("uc.url");
//链接地址
Properties sessionPro = new Properties();
sessionPro.put("mail.smtp.host", host);
sessionPro.put("mail.smtp.port",port);
sessionPro.put("mail.smtp.auth","true");
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getDefaultInstance(sessionPro,new MyAuthenticator(authuser,authpwd));
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address fromAddress = new InternetAddress(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address toAddress = new InternetAddress(email);
// 设置邮件消息的发送者
mailMessage.setFrom(fromAddress);
mailMessage.setFileName(title);
mailMessage.setDescription(title);
//指定邮件优先级 1:紧急 !表示 3:普通 5:缓慢
向下的箭头表示
mailMessage.setHeader("X-Priority","1");
mailMessage.setRecipient(Message.RecipientType.TO,toAddress);
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
mailMessage.setSubject("找回密码");
// MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象
Multipart mainPart = new MimeMultipart();
// 创建一个包含HTML内容的MimeBodyPart
BodyPart html = new MimeBodyPart();
//设置邮件内容
Map&String,String& props=new HashMap&String,String&();
props.put("title", title);
props.put("url", url);
props.put("userName",userDTO.getUserName());
props.put("password",password);
//读取邮件内容
String result=emailTemplate(props,"mail/findpwd_mail.vm");;
html.setContent(result,"text/charset=utf-8");
mainPart.addBodyPart(html);
// 将MiniMultipart对象设置为邮件内容
mailMessage.setContent(mainPart);
//保存要发送的邮件
mailMessage.saveChanges();
//发送邮件
Transport.send(mailMessage);
StringBuilder sb = new StringBuilder();
sb.append("我们已向您的");
sb.append(email.substring(email.indexOf("@")+1,email.length())+"'");
sb.append("邮箱发送了一封密码找回邮件,请您注意");
sb.append("&font color='red'&&a target='_blank' href='http://mail.");
sb.append(email.substring(email.indexOf("@")+1,email.length())+"'");
sb.append("&");
sb.append("接收邮件");
sb.append("&/a&&/font&");
sb.append("!");
addError(sb.toString(),"success_msg");
} catch (Exception ex) {
System.out.println(ex.getMessage());
addError("网络连接失败!检查您的网络是否正常!");
IOUtils.closeQuietly(in);
3: 添加系统邮箱的配置文件,放到类路径下,取名为:mail.properties
uc.title=xxxx用户中心
mail.host=
mail.username=renwg
mail.password=xxxx
mail.from=
mail.port=25
4:添加发送邮箱的模板引擎,放到类路径下的 mail 文件夹下 取名为:findpwd_mail.vm
&div id="contentDiv" style="font-size:14height:padding:15px 0 10px 15*padding:15px 0 0 15overflow:line-height:170%;min-height:100_height:100" class="" &
&table id="" width="100%" cellpadding="0" cellspacing="0" border="0"&
&td valign="top" style="font-size:14padding:0;height:min-height:font-family: 'lucida Grande',V" class="body"&
&div id="mailContentContainer" class="left"&
&style type='text/css'&
body,td,th {
font-size: 12
color: #393939;
line-height: 24
.te2 {WIDTH: 80 HEIGHT: 17BACKGROUND-COLOR: #border: 1px solid #A6BEE0;}
.font_line28 {line-height: 32 ; ;}
.font_blue14_bold {color:#1369BF;font-weight: font-size: 14line-height: 23}
.font_blue122_bold {color:#4D728F;font-weight:;}
.font_red12 { font-size:12color:#FF0000;}
.fant_hui12 { font-size:12color:#B9B9B9;}
.font_blue12{color:#4D728F; padding-right: 7}
.font_blue12 a:link{ color:#4D728F; text-decoration:}
.font_blue12 a:visited{color:#4D728F; text-decoration:}
.font_blue12 a:hover {color:#4D728F; text-decoration:}
&table width='500' border='0' align='center' cellpadding='0' cellspacing='1' bgcolor='#0BA5EB'&
&td align='left' valign='top' bgcolor='#FFFFFF'&
&table width='100%' border='0' cellspacing='0' cellpadding='0'&
&td width='39' height='26' background='/images/cun365/reg_r2_c4.jpg'&&img src='/images/cun365/reg_r2_c21.jpg' width='34' height='26'/&&/td&
&td width='577' align='left' valign='bottom' background='/images/cun365/reg_r2_c4.jpg' class='font_blue14_bold'&确认邮件&/td&
&td width='32' align='left' valign='middle' background='/images/cun365/reg_r2_c4.jpg'&&img src='/images/cun365/gif-0081.gif' width='23' height='17'/&&/td&
&td align='center' valign='top' bgcolor='#FFFFFF'&
&table width='92%' border='0' cellspacing='0' cellpadding='0'&
&td height='12'&&/td&
&td align='left' valign='top'&
尊敬的&span class='font_red12'&$!{userName}&/span&,您好:&br/&
&&& 请您点击下面链接来修复您的登录密码:&br/&&span class='font_red12'&
&a href='$!{password}'&$!{password}&/a&&/span&
&td height='13' align='left' valign='top'&&/td&
&td height='13' align='left' valign='top' background='/images/cun365/reg_line.jpg'&&/td&
&td align='left' valign='top'&
&span class='font_blue122_bold'&为了确保您的帐号安全,该链接仅3天内访问有效。&/span&&br/&
#set($start=$!{password.indexOf('guest')})
如果该链接已经失效,请您点击 &a href='$!{password.substring(0,$start)}guest/get_pwd_mail.action' target="_blank" class='font_blue12'&这里&/a& 重新获取修复密码邮件。
&span class='fant_hui12'&&br/&(如果不能点击该链接地址,请复制并粘贴到浏览器的地址输入框)&/span&
&td height='40' align='center' valign='middle'&&span class='font_gray14'&
&a href='$!{password.substring(0,$start)}login?service=$!{password.substring(0,$start)}passport/default.action' target='_blank'&&img src='/images/cun365/but-1.gif' width='203' height='24' border=0//&&/a&
&/span&&/td&
&td height='13' align='left' valign='top'&&/td&
&td height='13' align='left' valign='top' background='/images/cun365/reg_line.jpg'&&/td&
&td align='left' valign='top'&
&div id="mailContentContainer"&
&&&& &&&如果您有任何问题,请查看&a href="#"&隐私权保护规则&/a&&br/&
&&&&&服务热线:
电子邮箱:&a href="mailto:"&&/a&
&p& 此邮件为系统所发,请勿直接回复。& & &br/&&br/&&/p&
&td align='left' valign='top'&&&/td&
&td width="170"&&&/td&
5:此是发送邮件的 Action 。也给大家贴出来供参考一下。
* 把密码发到邮箱
public String sendEmail(){
if(StringUtils.isEmpty(userName)){
WebUtil.addError("用户名不能为空");
return INPUT;
if (StringUtils.isEmpty(email)) {
WebUtil.addError("用户邮件地址不能为空");
return INPUT;
if (!EmailValidator.getInstance().isValid(email)) {
WebUtil.addError("用户邮件地址格式不正确");
return INPUT;
if (!WebUtil.checkVerifycode(verifycode)) {
WebUtil.addError("验证码输入错误!");
return INPUT;
UserDTO user = WebUtil.getUserByUserName(userName);
if (user == null) {
WebUtil.addError("找不到此用户");
return INPUT;
if(!user.getEmail().equals(email)){
WebUtil.addError("用户名和邮箱地址不匹配");
return INPUT;
//产生出来的新密码
String emailUrl = "";
//这里看情况而定,你可以采用更好的算法
emailUrl = WebUtil.getBasePath(ServletActionContext.getRequest())+"resetpwd?sid="+DESPlus.encrypt(userName)+"&type="+user.getPassword();
} catch (Exception e1) {
WebUtil.sendEmail(user, emailUrl,email);
} catch (Exception e) {
return INPUT;
return SUCCESS;
具体页面,我想就不用我在贴出来了吧。
如果您想提高自己的技术水平,欢迎加入本站官方1号QQ群:&&,&&2号QQ群:,在群里结识技术精英和交流技术^_^
本站联系邮箱:

我要回帖

更多关于 二级建造师复习题集 的文章

 

随机推荐