1、In Action
(1)根据添加信息(insert)来考虑表中的字段,进行建表。使用PD画出ER图。要注意字段的数据类型的确定以及建表要满足三范式,减少数据冗余;
(2)表建好后,根据表中各个字段来建pojo中的属性。要注意属性的数据类型和字段的数据类型要一致;
(3)根据pojo中的属性确定bean的属性,直接拷贝即可,用于页面展示。在bean中,统一使用String类型变量接收前台页面传递的参数;每个HTML表单对应一个bean。HTML表单中的字段和bean中的属性一一对应。
(4)自顶向下,依次定出action、manager、dao。先写出轮廓,跑通整个流程,再写具体实现,一点点累加,便于调试错误;
(5)根据数据实体和具体业务逻辑,使用StarUML画类图,进行OOA和OOD,灵活运用设计模式。
(6)API命名:
CRUD:add,get,update,delete,[list]
严格区分单复数形式,单数表示对象,复数表示对象集合。
对象、属性最好单个单词。
(7)前后台都要校验。
(8)按照资源方式组织数据接口,对前端开发帮助很大。即通过REST来实现资源的增、删、改、查。
(9)软件开发,思路最重要!代码开发多了,思路就有了。
a、一个版本一个版本递增的开发; 每个版本增加一点内容;
b、总结开发思路;第一步怎么做,下一步怎么做?
c、用文档记录开发的思路,即第一个版本开发实现了什么功能以及开发步骤,下一个版本实现了什么功能等等?
d、程序员进行程序开发时,不要仅仅停留在代码,要深入到底层的运行机制,才可以对程序的运行机制有更准备的把握;
(10)网页模板
request到template.jsp文件(此文件假设包括三个部分,即title、banner、body)
web客户——> title
banner———————>include:banner.jsp
body————————>include:showcart.jsp
(11)一步一步的定位。根据结果进行分析。
(12)分页控件
假分页:
基本思想是将所有的数据从数据库中取出,只显示有用的部分。靠的是程序的算法,实际上就是在ResultSet上进行操作。
真分页:(数据库中的一种实现)
任何数据库都会提供分页的函数操作:Oracle、MySQL(limit,即limit 开始的记录, 要查询的行数)、SQL Server(top)
基本思想是在数据库中编写特定的SQL语句。程序中只读取有用的部分,没用的部分不会加载到内存中。
(13)
2、TIPS
(1)、VO就是POJO。
(2)、先做完基本功能,然后对输入的数据进行验证。主方法中代码尽可能少,再考虑代码的可重用性。
(3)、当发现代码中重复地复制/粘贴时,就可以考虑将之形成为一个类进行调用。
(4)、在类的设计中,永远不要去继承一个已经实现好的类,只能继承抽象类或实现接口。
(5)、一个设计良好的类,应重写Object类中的equals()、hashCode()、toString()方法。
(6)、在action层中接收参数,要写健壮,要做空指针处理。
(7)、业务逻辑放到manage层,如if...else...不要放在action层,放在manage层处理。
(8)、dao层要写健壮,传入的是bean或map,返回的是bean或list。
(9)、查询:所有的记录总数以及查询第几页的数据;
(10)、多思考,尝试用不同、多种方法去解决问题。(发散性思维)
(11)、当程序中有0、1这样的数字或字符串出现时,最好用常量代替。常量名很重要,做到见名知意。
(12)、spring针对每一层(action.manager、dao)都有一个配置文件;ibatis有2个配置文件。sqlmap有namespace,每个实体类都对应一个xml配置文件。
(13)、类设计,编写时先完成基本功能的实现,然后再对实现功能的代码结构进行优化。
(14)
2、PS
(1)Java Web开发环境:JDK、IDE、java web服务器
JDK,一般指sun公司发布的JDK,也有其他的JDK,如IBM的JDK、BEA的JRocket等。从Java 5.0开始,Java web技术也称为Java EE。Java EE应用程序的运行需要Java EE类库的支持。
安装好JDK后,设置JAVA_HOME环境变量以及将JDK下的bin目录添加到PATH环境变量。
eclipse需要Java运行环境。
Eclipse WTP是Eclipse官方提供的web开发工具。
Java web服务器在Java EE规范中也叫做容器。
(2)web容器在启动时,从web.xml文件中读取配置信息,装载web应用。
web容器运行时,不会检测web.xml、struts配置文件的更新而重新加载它。
若struts框架不能处理的异常,会把错误抛给web容器。容器会查看web.xml文件中是否配置了<error-page>元素。若存在,则返回<error-page>元素的<location>子元素指定的错误页面。否则直接将错误抛给用户。
(3)webApp部署好后,启动Tomcat会自动发布webApp。首先是实例化Filter,并调用其init()方法初始化。然后根据<load-on-startup>的数值(数值为0或正数,数值越小越先加载)来依次加载servlet,并调用其init()方法进行初始化。
若没有为servlet配置<load-on-startup>属性,则当web应用启动时servlet容器不会加载这个servlet,只有当用户首次访问此servlet时才加载。
(4)
web调试时,一定要服务器以调试模式启动。然后在程序中打断点,通过浏览器访问,这样程序运行到断点处就会暂停运行。
(5)jsp放到WEB-INF文件夹中,可防止外界直接通过URL来访问Jsp页面,此时jsp一定要是servlet或action的后继页面,才可以被访问到。
(6)EL表达式是JSP2.0规范,需要Tomcat支持的。Tomcat6才支持EL表达式。
(7)编码
用户提交的查询数据(即get请求),默认采用的是ISO-8859-1编码。
request.setCharacterEncoding("utf-8"); //设置request编码方式,即设置使用utf-8来解析请求参数;
response.setCharacterEncoding("utf-8"); //设置response编码方式
(8)JNDI
JNDI:为某个java对象起一个名字。如为Tomcat中的数据源起一个名字,从而让程序可通过该名字访问该数据源对象。(Tomcat内置了DBCP的数据源实现)
若web应用访问了由servlet容器管理的某个JNDI资源,需要在web.xml中对这个JNDI资源的引用声明,表示资源引用的元素为<resource-ref>。
(9)session
servlet容器为HttpSession分配唯一标识符sessionID。servlet容器把sessionID作为cookie保存在客户的浏览器中。若浏览器禁止cookie,servlet容器可重写客户请求的url,把sessionID添加到url信息中。HttpServletResponse接口提供了重写url的方法:encodeURL(url)。
当用户第一次访问web应用中支持session的网页时,就会产生一个新的session。接下来当用户访问这个web应用的不同网页时,始终处于同一个session中。
每次用户发出HTTP请求,servlet容器可从HttpServletRequest对象中读取sessionID。根据sessionID找到相应的HttpSession对象。
设置session的三个方法:
a、在tomcat——conf——server.xml文件中定义。
b、在web.xml中定义
如:<session-config>
<session-timeout>30</session-timeout>
</session-config>
c、在程序中定义,如session.setMaxInactiveInternal(30);单位为秒。-1表示永不过期。
以下情况,session将结束生命周期,servlet容器会将session所占资源释放掉: a、session过期;
b、服务器端调用了HttpSession的invalidate()方法。
session持久化:
Tomcat采用Persistent Manager管理持久化session store。session store有两种实现: a、FileStore:将session数据保存在文件系统中;
b、JDBCStore:将session数据保存在数据库中。
(10)JNI
即java本地调用接口。通过此接口,java程序可和其它语言编写的本地程序通信。
(11) UTF-8、jar包、compiler,需要修改。
(12) web程序实际部署时常用WAR包部署。可以将web程序打成zip包,然后修改文件后缀为WAR。
(13) 服务器知道了网址,便将网页的内容输出给浏览器。输出的内容可以是html文本,也可以是二进制数据,如图片、声音、视频等。浏览器将html文本显示为网页,将二进制内容还原为图片、声音、视频。
telnet 80 表示连接服务器的80端口。
post方式发送的命令,需要提供提交的数据类型及长度。数据类型有两种,普通的文本数据(ASCII码数据),类型为application/x-www-form-urlencoded,一种是文件数据(二进制数据),类型为multipart/form-data。
Tomcat、浏览器已经实现好了HTTP协议。
(14) Web开发中整合S2SH
先导入Spring框架和支持Struts2的插件,接着导入Struts2框架,然后将Hibernate框架配置在Spring容器中。
让Spring管理Struts中Action的初始化和Hibernate的会话工厂(SessionFactory)。
(15)Java web应用的目录结构:
webapp名
WEB-INF jsp、html等
web.xml lib classes tld文件等
(16)数据源(数据库连接池)
web应用
javax.sql.DataSource接口(所有数据源必须实现此接口) DBCP数据源 JDBC Pool数据源
数据库
数据库所能支持的并发连接数是有限的。
连接未关闭,将导致数据库系统中的内存泄露。
同一个连接使用次数过多,将导致连接不稳定。
连接池基本思想:预先建立一些连接,放置于内存对象中保存。当程序需要建立数据库连接时,只需从内存中取一个来用而不用新建。
(17) Apache+mod_jk+Tomcat或JBoss
request——>(Apache监听端口)Apache——>mod_jk——>(应用服务器AJP端口)JBoss或Tomcat(应用服务器端口)
(18)典型的web应用一般都有:
a、登陆页,是整个应用的入口。当用户登录后,应用会将用户相关的安全信息放到session中。
b、有一个filter,它拦截请求,检查每个请求相关的session中是否包含有用户安全信息,若没有,请求被重定向到登陆页,要求用户提供安全信息。
(19)——>开发文档——>API文档,看SDK示例来获取数据。 SDK封装了调用API的请求、加密、返回解析等一些必要过程。
(20)web服务器跟踪客户的状态通常有四种方法:
a、在form表单中添加隐藏字段
b、重写包含额外参数的URL
c、使用cookie
d、使用session
session的状态跟踪有两种方式:
a、使用cookie保留和传递sessionID,要求浏览器允许cookie,不要求程序对url处理。 b、使用URL重写。显式在浏览器和服务器之间传递sessionID。要求程序对url进行编码,对浏览器没有要求。
URL编码函数:encodeURL()。此方法由HttpServletResponse接口提供。
servlet容器为HttpSession分配唯一标识符session ID。servlet容器将session ID作为cookie保存在客户的浏览器中。
每次客户发出HTTP请求,servlet容器可从HttpRequest对象中读取session ID,根据session ID找到相应的HttpSession对象。
(21)阻止浏览器对页面缓存
response.setHeader("Cache-Control", "no-store"); //HTTP1.1
response.setHeader("Pragma", "no-cache"); //HTTP1.0
response.setHeader("Expires", 0); //prevent cache at proxy server
写ajax时,必须要阻止客户端的缓存。
第二篇:用JAVA开发WEB Service(学习总结)
用JAVA开发WEB Service
一学习前的准备
开发环境 JBOSS4.05+axis1.4+JDK1.5
axis1.4下载地址: http://www.apache.org/dist/ws/axis/1_4/,选择axis-bin-1_4.zip
所需要的JAR包:
二部署axis
以我们CreateGWS405产品为例,在产品server\default\deploy目录下新建一个应用,比如叫myService.war。在里面新建文件夹“WEB-INF”,将axis1.4以下目录中的web.xml文件拷贝到“WEB-INF”下。“axis-bin-1_4\axis-1_4\webapps\axis\WEB-INF“。然后将jar包拷贝到产品server\default\lib下。至此部署完毕。
三开发webService服务端
用编辑器编写一个简单的服务类,代码如下:
import java.util.*;
import java.text.*;
public class SayHello {
public String say(String name){
System.out.println("call webservice say.....");
return " Hello " + name;
}
}
将该类复制到myService.war中与“WEB-INF”同级目录,然后更改其名字为”SayHello.jws”。
启动CreateGWS405,在浏览器地址输入http://localhost:88/myService/SayHello.jws?wsdl打开页面后你会看到
Click to see the WSDL <--点击链接,如果你上面的步骤都正常,类也没有带
其他包的话,那么就生成了wsdl了。
至此webService服务端发布成功,接下来就是编写客户端了。
四 开发webService客户端。(DLL方式)
这里为了方便测试,我们就以CreateGWS405产品为客户端,在create.war下新建一个JSP页面,代码如下:
String urlname = "http://localhost:88/myService/SayHello.jws?wsdl";
Service s = new Service();
Call call = (Call) s.createCall();
//要调用的方法名称
call.setOperationName("say");
call.setTargetEndpointAddress(urlname);
//方法传入一个String型参数,返回值也是String
String val = (String) call.invoke(new Object[] { "haha" });
System.out.println(val);
需要导入:import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
至此一个简单的客户端就编写好了。上面服务端的方法参数是String,返回值也是String,而实际业务中可能还需要以int,boolean等类型做参数,而且参数不止一个。返回值有时是int有时又是集合ArrayList那该怎么做呢,请看下面这个服务端代码
import java.util.*;
import java.text.*;
public class SayHello {
public String say(String name){
System.out.println("call webservice say.....");
return " Hello " + name;
}
public ArrayList getList(String str){
ArrayList strs = new ArrayList();
System.out.println("call webservice getList.....");
strs.add("A");
strs.add("B");
strs.add("C");
strs.add(str);
return strs;
}
public String [] getStrs(String str,int a){
System.out.println("call webservice getStrs.....");
String[] abc = new String[a];
abc[0]=str;
return abc;
}
public int getInt(String arg){
System.out.println("call webservice getInt.....");
return arg.length();
}
}
这个服务端有4个方法,分别返回不同类型的值。客户端就要改成
String urlname = "http://localhost:8080/aixs_proxy_demo/SayHello.jws?wsdl";
Service s = new Service();
try {
Call call = (Call) s.createCall();
//要调用的方法名称
call.setOperationName("say");
call.setTargetEndpointAddress(urlname);
//方法传入一个String型参数,返回值也是String
String val = (String) call.invoke(new Object[] { "haha" });
System.out.println(val);
Call call4 = (Call) s.createCall();
//要调用的方法名称
call4.setTargetEndpointAddress(urlname);
call4.setOperationName("getList");
String st1 = "abc";
//传入参数类型为String
call4.addParameter(new QName("st1"), XMLType.XSD_STRING, ParameterMode.IN);
//返回一个ArrayList
call4.setReturnType(new QName("ArrayList"), ArrayList.class);
ArrayList list = (ArrayList) call4.invoke(new Object[] { st1 });
System.out.println("+++++" + list.size());
Call call2 = (Call) s.createCall();
String st2 = "abc";
int count = 303;
call2.setOperationName("getStrs");
call2.setTargetEndpointAddress(urlname);
//传入参数类型为String和int
call2.addParameter(new QName("st2"), XMLType.XSD_STRING, ParameterMode.IN);
call2.addParameter(new QName("count"), XMLType.XSD_INT, ParameterMode.IN);
//返回一个String[]
call2.setReturnType(new QName("String[]"), String[].class);
String[] strs = (String[]) call2.invoke(new Object[] { st2,
Integer.valueOf(count) });
System.out.println("-----" + strs.length);
Call call3 = (Call) s.createCall();
String st3 = "abcdefg";
call3.setOperationName("getInt");
call3.setTargetEndpointAddress(urlname);
//传入参数类型为String
call3.addParameter(new QName("st3"), XMLType.XSD_STRING, ParameterMode.IN);
//返回一个int
call3.setReturnType(new QName("Integer"), Integer.class);
Integer getint = (Integer) call3.invoke(new Object[] {st3});
System.out.println(getint);
} catch (Exception e) {
e.printStackTrace();
}
需要导入: import java.util.ArrayList;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
学习中需要注意的地方:
1、 在客户端调用其他程序的类时需要先把外部类引入到myService.war\WEB-INF\下新建classes文件夹,包路径与原类相同,如果是jar文件,则需要复制到myService.war\WEB-INF\lib下。这样.jws格式文件才能正确编译为.class文件。
2、 调用其他服务器上的webservice时需要注意一定要将包导入完全,如果包缺少会影响使用。
五开发webService客户端。Dynamic Proxy方式 (代理方式)
还是以上面那个服务端为例,用代理的方式来调用webService我们只需要对客户端的代码进行修改就可以了,代码如下
String wsdlUrl = "http://localhost:8080/aixs_proxy_demo/SayHello.jws?wsdl";
String nameSpaceUri = "http://localhost:8080/aixs_proxy_demo/SayHello.jws";
// 服务名
String serviceName = "SayHelloService";
// 服务
String portName = "SayHello";
// 创建代理对像
ServiceFactory serviceFactory;
try {
serviceFactory = ServiceFactory.newInstance();
//创建远程服务
Service service = (Service) serviceFactory.createService(new URL(wsdlUrl), new QName(
nameSpaceUri, serviceName));
//向上转型为接口
MyServiceInterface proxy = (MyServiceInterface) service.getPort(
new QName(nameSpaceUri, portName), MyServiceInterface.class);
//调用相应方法
System.out.println("proxy.say ----"
+ proxy.say("li lei"));
System.out.println("proxy.getList ----"
+ proxy.getList("AAAA").size());
System.out.println("proxy.getStrs ----"
+ proxy.getStrs("BBBB",10).length);
System.out.println("proxy.getInt ----"
+ proxy.getInt("ABCDEFG"));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
需要导入:
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.ServiceFactory;
import org.apache.axis.client.Service;
MyServiceInterface接口类的编写
import java.rmi.Remote;
import java.util.*;
publicinterface MyServiceInterface extends Remote{
public String say(String name);
public ArrayList getList(String str);
public String [] getStrs(String str,int a);
publicint getInt(String arg);
}
需要注意的是:
1、 接口必须继承Remote类,才能做代理
2、 接口里面的方法必须和jws文件中的方法保持一致。