本文主要是介绍项目开发全纪录(三),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
21、GET和POST的区别
首先要讲一点get和post都是浏览器与服务器交互的一种方式.但是对于get来说它不仅仅按常规的理解那样只有取的过程,它也有向服务器发送信息的过程,它之所以也能传送数据,只是用来告诉服务器,你到底需要什么样的数据。
所有的人都知道如下的区别:
Post传输数据时,不需要在URL中显示出来,而Get方法要在URL中显示。
Post传输的数据量大,可以达到2M,而Get方法由于受到URL长度的限制,只能传递大约1024字节
Post顾名思义,就是为了将数据传送到服务器端,Get就是为了从服务器取得数据,而Get之所以也能传送数据,只是用来设计告诉服务器,你到底需要什么样的数据。Post的信息作为Http请求的内容,而Get是在Http头部传输的。
具体描述:
HTTP 定义了与服务器交互的不同方法,最基本的方法是 GET 和 POST。事实上 GET 适用于多数请求,而保留 POST 仅用于更新站点。根据 HTTP 规范,GET 用于信息获取,而且应该是 安全的和 幂等的。所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。幂等的意味着对同一 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。从根本上讲,其目标是当用户打开一个链接时,她可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的注解应该通过 POST 请求实现,因为在注解提交之后站点已经不同了(比方说文章下面出现一条注解);
在FORM提交的时候,如果不指定Method,则默认为GET请求,Form中提交的数据将会附加在url之后,以?分开与url分开。字母数字字符原样发送,但空格转换为“+“号,其它符号转换为%XX,其中XX为该符号以16进制表示的ASCII(或ISO Latin-1)值。GET请求请提交的数据放置在HTTP请求协议头中,而POST提交的数据则放在实体数据中;
GET方式提交的数据最多只能有1024字节,而POST则没有此限制。
22、同步和异步
同步这里的“同”并不是“一起”的意思,而是“协同”的意思。
同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。
“同”字从字面上容易理解为一起动作,其实不是,“同”字是指协同、协助、互相配合。
如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A在继续操作。
同步就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其他线程也不能调用这个方法。按照这个定义,其实绝大多数函数都是同步调用。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。最常见的例子就是SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕之后,该函数才把消息处理函数所返回的LRESULT值返回给调用者。
在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多一个线程访问,以保证数据的完整性。
异步的概念和同步相对,当一个异步过程调用发出后,调用者不能立刻得到结果,实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
实例:叫人吃饭
比如说你正在忙一件事件,你朋友来叫你去吃饭,现在来看看同步和异步对于这个事情是怎么处理的。
同步:你朋友来你的办公室通知你,但是你的工作还没完成,所以你的朋友就会一直等你,等你做完以后才一起去吃饭。
异步:你朋友来你的办公室通知你,你说好,你想去吧,我待会就来。你朋友得到你的口头答应以后,就离开你的办公室去找餐厅点菜去了,你忙完工作后,就去餐厅找你朋友,一起吃饭。
看看下面的图:
同步:
23、如何使用Ant
这里只讲一下简单的应用,具体请参考相关的文档:
第一步:从http://ant.apache.org 下载 apache-ant-1.7.0-bin.zip,解压到你自己的目录,我的:E:\apache-ant-1.7.0
第二步:配置 JAVA_HOME 和 ANT_HOME
配置完成后,打开dos窗口,输入 ant 回车,如果提示:
Buildfile: build.xml does not exist!
Build failed
则说明配置完成
第三步:创建自己的工程
我的工程:test
目录结构:
D:\work\code\test_core\src
D:\work\code\test_core\lib
第四步:编写build.xml
24、单元测试和集成测试
单元测试:单元测试是开发者编写的一小段代码,用于检验目标代码的一个很小的、很明确的功能是否正确。
集成测试:集成测试是在功能模块开发完成后,为验证功能模块之间匹配调用的正确性而进行的测试。
在单元测试时,往往需要通过模拟对象屏蔽外在模块的依赖,而集成测试恰恰是要验证模块
之间集成后的正确性。
1、Junit+EasyMock进行单元测试
导入需要的jar包:
下面是一个简单的测试例子
UserDao接口:
public interface UserDao {public int getMatchCount(String userName,String password);
}
UserService接口:
public interface UserService {boolean hasMatchUser(String userName,String password);
}
UserService接口的实现UserServiceImpl:
public class UserServiceImpl implements UserService {private UserDao userDao;public boolean hasMatchUser(String userName, String password) {// TODO Auto-generated method stubint matchCount=userDao.getMatchCount(userName, password);return matchCount>0;}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}
UserServiceImpl要用到userDao组件的实现,但是现在的情况是userDao的实现并没有写好,或者是userDao的实现是由另外的人员编写,这时候要测试自己写的这个UserServiceImpl实现类是否正确,就要用到上面讲的那个EasyMock测试框架了,我们这里是和Junit框架结合使用的.下面是测试类:
UserServiceImplTest:
public class UserServiceImplTest extends TestCase {private UserServiceImpl userService;@Overrideprotected void setUp() throws Exception{userService=new UserServiceImpl();super.setUp();}public void testHasMatchUser(){UserDao userDao=EasyMock.createMock(UserDao.class);userService.setUserDao(userDao);EasyMock.expect(userDao.getMatchCount("tom","654321")).andReturn(0);EasyMock.expect(userDao.getMatchCount("tom","123456")).andReturn(1);EasyMock.replay(userDao);assertEquals(userService.hasMatchUser("tom","654321"),false);assertEquals(userService.hasMatchUser("tom","123456"),true);EasyMock.verify(userDao);}
}
2、集成测试(Spring提供的模拟类)
Spring在org.springframework.mock包中为一些依赖于容器的接口提供了模拟类,这样用户可以在不启动容器的情况下执行单元测试,提供单元测试的运行效率。
我们在实际的使用过程中,对于不想启动Spring容器,又想做集成测试,那么我们就可以继承AbstractDependencyInjectionSpringContextTests类,这个类所添加的主要功能是其属性能被Spring容器中的Bean自动装配,用户无须手工通过ApplicationContext#getBean()从容器中获取目标Bean自行装配。
看下面例子:
package email;import org.springframework.test.AbstractDependencyInjectionSpringContextTests;/*** @project_name jms* @file_name Login.java* @author tianhandigeng* @version Oct 12, 2010 10:22:17 PM* @declaration*/
public class Login extends AbstractDependencyInjectionSpringContextTests{// 设置邮件发送者private UserMessageProducer userMessageProducer;// 设置注册人员的信息private PersonInfo personInfo = new PersonInfo();public UserMessageProducer getUserMessageProducer() {return userMessageProducer;}public void setUserMessageProducer(UserMessageProducer userMessageProducer) {this.userMessageProducer = userMessageProducer;}@Overrideprotected String[] getConfigLocations(){return new String[]{"classpath:applicationContext.xml"};}// 注册后发送邮件public void testSetEmail() {personInfo.setUserName("胡学汪");personInfo.setPassword("14981498");personInfo.setEmail("tianhandigeng@sohu.com");this.getUserMessageProducer().sendUserLoginInformationMail(personInfo);}
}
【根据描述,userMessageProducer属性就不需要我们手动的从容器拿出Bean】
25、JMS(ActiveMQ)和Spring整合发送邮件
1、在使用ActiveMQ5.4.1的时候,关闭broker重新启动的时候,出现异常java.io.EOFException:Chunk stream does
not exist at page on broker start
暂时的解决办法:
在activemq.xml中<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" ataDirectory="${activemq.base}/data" destroyApplicationContextOnStop="true" schedulerSupport="false">
加上红色的配置。
2、现在来讲ActiveMQ与Spring的整合
在这里我们以注册后发送邮件这个例子来讲两者的整合
第一步:导入jar包
上面有些jar并不是一定需要的,有的是进行测试用的
第二步:这里本来配置文件是一点一点写的,在这里我就全给出了:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:amq="http://activemq.apache.org/schema/core"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://activemq.apache.org/schema/corehttp://activemq.apache.org/schema/core/activemq-core-5.3.2.xsd"><!--定义内嵌的ActiveMQ Broker,使用消息存储机制,服务器重启后,消息不会丢失 --><amq:broker useJmx="false" persistent="true"><amq:persistenceAdapter><amq:amqPersistenceAdapter directory="e:/zuwoba" /></amq:persistenceAdapter><!-- The transport connectors ActiveMQ will listen to ... --><amq:transportConnectors><amq:transportConnector uri="tcp://localhost:61616" /></amq:transportConnectors></amq:broker><!-- 配置JMS Connection Factory,用到缓存功能 --><bean id="jmsFactory"class="org.apache.activemq.pool.PooledConnectionFactory"><property name="connectionFactory"><beanclass="org.apache.activemq.ActiveMQConnectionFactory"><property name="brokerURL" value="tcp://localhost:61616" /></bean></property></bean><!-- 配置消息发送目的地 --><bean id="queueDestination"class="org.apache.activemq.command.ActiveMQQueue"><constructor-arg value="MY.queue" /></bean><!-- 配置Spring中消息发送的JMS Template --><bean id="producerJmsTemplate"class="org.springframework.jms.core.JmsTemplate"><property name="connectionFactory"><beanclass="org.springframework.jms.connection.SingleConnectionFactory"><property name="targetConnectionFactory"ref="jmsFactory" /></bean></property><!-- 配置发送地址 --><property name="defaultDestination" ref="queueDestination" /><!-- 增加一个信息转换器 --><property name="messageConverter" ref="userMessageConverter" /></bean><!-- 配置消息转换器 --><bean id="userMessageConverter"class="com.zuwoba.util.mail.UserMessageConverter"></bean><!-- 配置消息发送者 --><bean id="userMessageProducer"class="com.zuwoba.util.mail.UserMessageProducer"><property name="jmsTemplate" ref="producerJmsTemplate" /></bean><!-- 配置消息接收者 --><bean id="userMessageConsumer"class="com.zuwoba.util.mail.UserMessageConsumer"><property name="mailService" ref="mailService" /></bean><!-- 配置Mail Service --><bean id="mailService"class="com.zuwoba.service.impl.MailServiceImpl"><property name="sender" ref="sender" /><property name="freeMarkerConfigurer" ref="freeMarkerConfigurer"/></bean><!-- 配置邮件模板 --><bean id="freeMarkerConfigurer"class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"><property name="templateLoaderPath" value="classpath:mailTemplate"/><property name="freemarkerSettings"><props><prop key="template_update_delay">1800</prop><prop key="default_encoding">gbk</prop><prop key="locale">zh_CN</prop></props></property></bean><!-- 配置邮件发送者 --><bean id="sender"class="org.springframework.mail.javamail.JavaMailSenderImpl"><property name="host" value="smtp.sina.com" /><property name="username" value="tianhandigeng" /><property name="password" value="14981498" /><property name="javaMailProperties"><props><prop key="mail.smtp.auth">true</prop></props></property></bean><!-- 配置messageListener,用它来接收消息--><!-- 定义queue的侦听器 --><bean id="messageListener"class="org.springframework.jms.listener.adapter.MessageListenerAdapter"><constructor-arg ref="userMessageConsumer" /><property name="defaultListenerMethod" value="handleMessage" /><property name="messageConverter" ref="userMessageConverter" /></bean><!-- 定义queue的侦听容器 --><bean id="listenerContainer"class="org.springframework.jms.listener.DefaultMessageListenerContainer"><property name="concurrentConsumers" value="20" /><property name="connectionFactory" ref="jmsFactory" /><property name="destination" ref="queueDestination" /><property name="messageListener" ref="messageListener" /></bean> </beans>
第三步:我们现在写当用户点击注册以后,发送消息给ActiveMQ的类,也就是消息发送者:
UserMessageProducer.java
package email;import javax.jms.Queue;import org.springframework.jms.core.JmsTemplate;/*** @project_name jms* @file_name UserMessageProducer.java* @author tianhandigeng* @version Oct 12, 2010 8:41:59 PM* @declaration*/
public class UserMessageProducer {private JmsTemplate jmsTemplate;// 如果"目的地"属性放于jmsTemplate中,则不用添加此属性private Queue defaultDestination;public void sendUserLoginInformationMail(PersonInfo personInfo) {/*** 若"目的地"属性放于jmsTemplate中,则用此方式* getJmsTemplate().convertAndSend(personInfo);*/getJmsTemplate().convertAndSend(this.defaultDestination,personInfo);}public JmsTemplate getJmsTemplate() {return jmsTemplate;}public void setJmsTemplate(JmsTemplate jmsTemplate) {this.jmsTemplate = jmsTemplate;}public Queue getDefaultDestination() {return defaultDestination;}public void setDefaultDestination(Queue defaultDestination) {this.defaultDestination = defaultDestination;}}
第四步:因为我们传给ActiveMQ的是对象,所以要有一个消息转换类,将对象转换为ActiveMQ所能理解的message,同时当从ActiveMQ取出message时这个转换类也会将message转换为对象。
UserMessageConverter.java
package email;import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;import org.apache.activemq.command.ActiveMQObjectMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;/** * @project_name jms* @file_name UserMessageConverter.java* @author tianhandigeng* @version Oct 12, 2010 4:52:50 PM * @declaration */
public class UserMessageConverter implements MessageConverter {private static transient Log logger=LogFactory.getLog(UserMessageConverter.class);public Object fromMessage(Message message) throws JMSException,MessageConversionException {if(logger.isDebugEnabled()){logger.debug("Receive JMS message:"+message);}if(message instanceof ObjectMessage){ObjectMessage oMsg=(ObjectMessage)message;if(oMsg instanceof ActiveMQObjectMessage){ActiveMQObjectMessage aMsg=(ActiveMQObjectMessage)oMsg;try{PersonInfo personInfo=(PersonInfo)aMsg.getObject();return personInfo;}catch(Exception e){logger.error("Message:["+message+"]is not a instance of personInfo.");throw new JMSException("Message:["+message+"]is not a instance of personInfo.");}}else{logger.error("Message:["+message+"]is not"+"a instance of ActiveMQObjectMessage[personInfo].");throw new JMSException("Message:["+message+"] is not"+"a instance of ActiveMQObjectMessage[personInfo].");}}else{logger.error("Message:["+message+"] is not a instance of ObjectMessage.");throw new JMSException("Message:["+message+"] is not a instance of ObjectMessage.");}}public Message toMessage(Object obj, Session session) throws JMSException,MessageConversionException {if(logger.isDebugEnabled()){logger.debug("Convert User Object to JMS message:"+obj);}if(obj instanceof PersonInfo){ActiveMQObjectMessage msg=(ActiveMQObjectMessage)session.createObjectMessage();msg.setObject((PersonInfo)obj);return msg;}else{logger.error("Object:["+obj+"] is not a instance of PersonInfo.");throw new JMSException("Object:["+obj+"] is not a instance of PersonInfo.");}}}
第五步:从ActiveMQ中取出消息
UserMessageConsumer.java
package email;import javax.jms.JMSException;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.mail.MailSender;/*** @project_name jms* @file_name UserMessageConsumer.java* @author tianhandigeng* @version Oct 12, 2010 9:08:23 PM* @declaration*/
public class UserMessageConsumer {private static transient Log logger = LogFactory.getLog(UserMessageConsumer.class);private MailService mailService;public void handleMessage(PersonInfo personInfo) throws JMSException {if (logger.isDebugEnabled()) {logger.debug("Receive a User object from ActiveMQ:"+ personInfo.toString());}mailService.sendSimpleMail(personInfo);}public static Log getLogger() {return logger;}public static void setLogger(Log logger) {UserMessageConsumer.logger = logger;}public MailService getMailService() {return mailService;}public void setMailService(MailService mailService) {this.mailService = mailService;}
}
第六步:书写发送消息的业务类
MailService.java
package email;import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;/*** @project_name jms* @file_name MailService.java* @author tianhandigeng* @version Oct 16, 2010 3:10:26 PM* @declaration*/
public class MailService {private JavaMailSender sender;public JavaMailSender getSender() {return sender;}public void setSender(JavaMailSender sender) {this.sender = sender;}//发送邮件public void sendSimpleMail(PersonInfo personInfo){System.out.println("到这了");SimpleMailMessage msg=new SimpleMailMessage();msg.setFrom("tianhandigeng@sina.com");msg.setTo((String)personInfo.getEmail());msg.setSubject("注册成功");msg.setText("恭喜,您在组我吧网已经注册成功,你的用户名是:"+(String)personInfo.getUserName());sender.send(msg);System.out.println("成功发送邮件");}}
第六步:测试
package email;import org.springframework.test.AbstractDependencyInjectionSpringContextTests;/*** @project_name jms* @file_name Login.java* @author tianhandigeng* @version Oct 12, 2010 10:22:17 PM* @declaration*/
public class Login extends AbstractDependencyInjectionSpringContextTests{// 设置邮件发送者private UserMessageProducer userMessageProducer;// 设置注册人员的信息private PersonInfo personInfo = new PersonInfo();public UserMessageProducer getUserMessageProducer() {return userMessageProducer;}public void setUserMessageProducer(UserMessageProducer userMessageProducer) {this.userMessageProducer = userMessageProducer;}@Overrideprotected String[] getConfigLocations(){return new String[]{"classpath:applicationContext.xml"};}// 注册后发送邮件public void testSetEmail() {personInfo.setUserName("胡学汪");personInfo.setPassword("14981498");personInfo.setEmail("tianhandigeng@sohu.com");this.getUserMessageProducer().sendUserLoginInformationMail(personInfo);}
}
26、如何查看某端口的使用情况
有时候在开发过程中要看具体的端口被哪个进程占用,网上大都是说用“netstat”命令,但是在实际使用过程中并不够使用,在这里从网上找到了一个解决的办法:
在Windows命令窗口下执行:
netstat –aon|findstr “80”
TCP 127.0.0.1:80 0.0.0.0:0 LISTENING 2448
看到了吗,端口被进程号为2448的进程占用,继续执行下面命令
tasklist|findstr “2448”
thread.exe 2016 Console 0 16,064K
很清楚吧,thread占用了你的端口,Kill it
如果第二步查不到,那就开任务管理器,看哪个进程是2448,然后杀之即可。
如果需要查看其他端口,把80改掉即可
27、public/protected/private/unsigned
28、Struts 2 整合SiteMesh的步骤
第一步:添加Struts 2的jar包
第二部:添加SiteMesh jar包和Struts 2 SiteMesh插件jar包,所需的jar包如下
第三步:定义装饰器页面,一般在头部要加上这样
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
下面是常用的SiteMesh的三个标签
<decorator:title/><decorator:head/><decorator:body/>
29、URI和URL
这两个单词一直都没去弄到底有什么不同,以前总是觉得很模糊,现在来看看具体有什么不同:
URI : Uniform Resourse Identitier
URL: Uniform Resource Locations
字面去解释都是表示”统一资源定位符”的意思.但是看看后面的这两个单词,又可以看出两者有什么不同,URI强调的是”身份”,URL强调的是”位置”.
URI更为注重资源而不太注重位置,URI对于定位Internet上的资源是更为通用的架构.
URI有两种形式:一种是URL,另一种是URN
URL表示的是某台特定主机上的一个资源的具体路径,是一个精确地、固定的位置。
URN(uniform resource name)指的是某一块特定内容的唯一的名字,和资源所在的位置无关,是location-independent的,允许资源从一个地方移到另一个地方。
URN仍然是实验性的,还没有被广泛的采用.URN需要一个基础架构来支持解决资源定位问题。
所以说,现在URI基本上都是URL。
30、Struts 2 Action接收参数的3中方式
用Action属性接收参数
用DomainModel接收参数
用ModelDriven接收参数
在实际的开发中,一般都是用第一种,其次是第二种,第三种用得少,我觉得第一种自己用得习惯所以就用采用了第一种。
------未完待续-------
这篇关于项目开发全纪录(三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!