一 Javaweb 项目中常见的思想、思路从哪去、原则 反思回顾:

来源:互联网 发布:翻译机 知乎 编辑:程序博客网 时间:2024/06/16 02:29

1 分层;

2 封装;

3 发现问题本质,方法解决转化

4 字符串的拼接

5 一张表一个dao类一个servlet

6 根据隐含参数判断数据来源

7 数据放在哪,从哪取

8 命名统一 规范问题

 

 针对上述介绍中,部分一般性规律:

1 分层;常见为src

com.example.dao        //数据访问层

com.example.daoimpl

 

com.example.entity(或者com.example.bean)  //实体层 域模型层

 

com.example.service        //业务逻辑层

com.example.service.impl

 

com.example.util     //工具类层

 

com.example.web.cotroller   //表现层

com.example.web.filter

com.example.web.formbean

com.example.web.listener

com.example.web.ui

 

com.example.util.test    //工具测试类层

 

webRoot

   js  css  jsp  html  imgs  等等,要注意分门别类存放

 

2 封装  面向对象的思维方式,共同的部分要抽取出来

创建一个新的Javaweb项目

利用eclipse  hbuilder  等创建一个Java web项目,其中需要注意的地方

1、项目中,在创建src里的包层时,需要注意包层的名称需要用小写字母

2、包层的命名是 com为二级域名example为三级域名,这个一般是公司域名倒写+名称

3、导包 导库 将用到的的第三方包 、库导入相应的文件夹  

比如需要将数据库驱动程序jar包导入web-inf 下的lib文件夹中

4、注意各处的字符编码是否统一,建议为utf-8

5、需要在清单文件中配置的项目要记得配置

 

四  常见的问题及分析:

1 数据库的连接(此处以MyEclipse连接本地Oracle数据库 为例):

1)如何在MyEclipse中连接Oracle数据库?

准备阶段:首先要在本地计算机上正确安装Oracle 数据库软件,数据库管理客户端管理软件

扩展:具体的安装过程中可能出现一些问题比如:

  1 为何数据库提示无法安装?

如果你的电脑之前安装过Oracle 数据库,在清理过程中未彻底清理干净会出现此问题,这里需要特别注意的是,Oracle数据库特别霸道 变态,只要电脑中目前无论任何的文件夹、注册表等各种地方有一个与Oracle数据库相关的文件,都意味着未清理干净,具体我百度到了一个地址,介绍还算不错可以根据上面提示保证完全清理干净

https://wenku.baidu.com/view/df5196f3ba0d4a7302763ac7.html

http://blog.csdn.net/oceanaut/article/details/3863222

 

2 开启数据库需要的服务

连接数据库之前,一定要确保Oracle数据库的相关服务开启,否则无法使用,因为Oracle数据库没有界面显示,来证明是否开启,所以要检查oracle数据库最基本的服务是否开启

2 在使用Oracle数据库管理软件时,要Oracle数据库的账号 密码,怎么填?是多少?

这个在你安装Oracle数据库时需要填写的,所以在安装Oracle数据库时,要特别注意让你填写的东西  账号和密码一定要记住,这里要填的账号密码就是当时填写的

软件连接部分: 打开eclipse———>点击上方的window选项——>open perspective-->MyEclipse Database Explore在左侧单击右键,出现一个连接数据库的信息列表单,driverManager templates:数据库驱动程序的类型,这个会有MySQL sqlserver oracle等各版本选项

driver name:这个随便填写,作为数据库的名称

Connection URl: 连接数据库的地址  jdbc:axiondb:<database-name>[:<database-directory>]大致都类似于这个,尖括号为必填项,方括号可不写

user name;用户名  这个就是你使用数据库的账号

password:密码 也好理解

driver jars: 这个就是你使用的数据库驱动程序的jar包的路径,可以通过文件选择功能找到,(并且这个jar包是需要复制粘贴到web项目中——>web Root ——>WEB-INF——>lib文件夹内)driver className:这个在你完成上一步之后会自动生成

到此就填写可以了,直接下一步或者完成就可。左边会产生一个服务器样式的文件夹,双击,正常会在该图标下产生文件,不报错,应该就是连接成功了

3 当然每个项目中需要有一个dao方法,连接数据库,具体的Java代码写法,后面介绍

(2)在项目的dao层中,要写一个与数据库进行连接的具体方法BaseDao的单独的类或者一个方法具体代码参考如下。(为了在本文档书写自动有提示,让类的内容显示有层次感,于是写在script中,因为script中接

 Java代码)

<script type="text/javascript">

public class BaseDao{  //定义基本的BaseDao

//定义连接数据库用到的基本参数 包括驱动程序名,驱动程序的url数据库用户名、密码

String driver="";

String url="";

String username="";

String password="";

//创建连接数据用到的基本类对象 包括连接对象Connection  conn sql语句预编译对象PreparedStatement pst  调用数据库返回结果集ResultSet sql语句

Connection conn=null;

PreparedStatement pst=null;

Resultset res=null;

String sql=null;

try{

//Java虚拟机中加载数据库连接驱动程序  简称 加载驱动

Class.forName(driver);

//调用驱动程序管理器连接数据库的方法连接数据库   亦称 获取连接

conn=DriverManager.getConnection(url,username,password);

 

}catch(Exception e){

e.printStactrace();

}

//关闭数据库连接资源的方法

public int closeAll(Connection conn,PreparedStatement pst,ResultSet res){

//如果不为空,表示处于连接状态,所以关闭资源

if (res!=null) {

try {

res.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (pst!=null) {

try {

pst.close();

} catch (SQLException e) {

e.printStackTrace();

return 0;

}

}

if (conn!=null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

return 0;

}

}

return 1; //告诉调用者是否关闭资源成功

}

 

public int executeUpdate(String sql,Object...params){

//预编译语句的通用方法,

int result=0;

conn=getConnection();  //获取数据库连接

try {

pst=conn.prepareStatement(sql);  // sql语句进行预编译操作

for (int i = 0; i < params.length; i++) {  

//动态将sql语句的片段集合化为一句

pst.setObject(i+1, params[i]);

}

pst.executeUpdate();  //执行sql语句

} catch (SQLException e) {

e.printStackTrace();

}finally{

this.closeAll(conn, pst, res);

}

 

return result;

}

}

 

</script>

2 对于项目的分析

1

 

3 数据库中表的设计

数据库一般的三范式是要遵循的。

字段的取值范围的考虑

 

4 在数据库中建立表的方法

因为不同的数据库,一些细节方面略有不同,但是都有一些共通的地方

1)利用数据库管理软件工具直接按照分析好的表结构,进行建表

对于主键等的设置,一般命名格式为

主键名为  pk_表名_字段名,

外键名为  fk_参考的表名_字段名

2)利用sql语句在Java代码中进行创建

 

5 如何在Oracle数据库中设置字段自增(比如主键id int类型 自增为例)

oracle 数据库中,没有直接设置字段自增的控件,如果涉及,需要利用序列的形式进行

设置,具体方法以pl/sql 软件为例,假如需要设置以student 表中主键idint)自增为例

在左侧sequences ——>右键单击——>new建立一张序列表,序列表表名的命名格式为

seq_原表表名_自增字段名    seq_student_id  

 

而在dao层添加数据的方法中,id列则不需要从外界获取值,添加方法的sql语句格式为

 

sql="insert into 表名(主键id,字段名2..,字段名n) value(序列表表名.nextval,?,?,...?)";

例如:

sql="insert into student(id,name,age,..,address) value(seq_student_id.nextVal,?,?,...,?)"

在创建序列表时,注意内容的填写,以原表中新建,还未添加数据,且以int类型自增为例,序列表的填写

 

owner system  (表示数据库用户名)        next number 1 (因为原表中没有数据,从1开始)

Name  seq_student_id  (此处为序列表表名) increatment by  1  (表示每次自动增加1)

min value  1  (表示id1开始)           Cache size   20  (表示数字的位数)

max  value    (此处不填默认为某个最大数值)    

 

该处填写完,即表示序列表已经创建完成,不需要其他操作

 

6 当软件连接完数据库后,一般会开始新建一个web项目,然后在其中开始写实体类 数据库基本的增删改查的方法

实体类对应于数据库中的实体 包括常见的set get方法。

完成访问数据库的方法,为了更显层次,会创建接口dao  dao对应的实现类

实现类中有基本的增删改查方法,如果可能,还可能需要创建根据条件进行查询、模糊查询等方法,这些应该在项目分析中考虑到。

 

7 创建用户界面 html或者jsp文件

 

webRoot 下面创建 文件夹js  css  imgs 方便对各种资源文件进行管理

新创建html 或者jsp文件时,注意更改字符集,

8 创建html(静态网页) jsp(动态网页)中需要注意的问题:

(1) 注意网页布局和样式、 代码的分层独立

(2) 注意网页中应该记得导入与该网页相关的css  js  jQuery等相关的文件

9 创建好网页之后,即可开始书写业务逻辑层,完成前后台的逻辑对接

 

10 网页布局中 div css浮动 定位 清除浮动之间有哪些规律?

 

11 书写服务层的一般逻辑:

 

(1) 从网页获取暗含的请求参数、判断逻辑需求,根据需求确定服务类别,因为一张表可能对应一个服务类,里面有多个服务

(2) 获取请求页面的请求参数(这里的请求参数和业务相关)reques.getParameter("");

(3) 调用相应的dao层的方法

(4) 根据dao方法返回的结果,进行业务处理

12 书写服务层是最常见的字符编码问题如何解决?

 (1) 利用过滤器,直接将所有相关的配置进行字符过滤处理

 (2) 将涉及到的所有可能出现乱码等问题的地方进行字符设置处理

 常见的情景有:

a 服务类里,第一件事,加入  request.setCharsetEncording("utf-8");

b 每项服务中,如果涉及将数据库中的数据取出来,传到网页,则设置响应对象 response.setCharsetEncording("utf-8");

13 项目中,日期类的格式转换问题,怎么解决?

 

(一)如果bean 中实体类导入的包是Java.util包,则以学生类 student为例:

1、实体类中的日期set get方法各自的书写

 

2dao 中,添加add 方法中,关于日期的项 语句书写

 

3servlet中,

1)完成添加含有日期的数据的功能时, 从网页html或者jsp时,获取请求参数

String time=request.getParameter("birthday_day");

//假设网页上生日是通过input标签name="birthday_day"传入

//因为网页传过来的都是字符串,所以此句是一定的。

 

Student  student=new Student();

student.setBirthday(?);

StudentDao dao=new StudentDao();

dao.add(student);

  2)完成根据条件查询数据,从数据库中查询到数据后的处理;

 StudentDao dao=new StudentDao();

 List<Student> list=dao.find();

//如果此处是将查询到的list作为结果返回到jsp界面

request.setAttribute("result",list);

request.getRequestDispatcher("index.jsp").forward(request,response);

 

4、网页中

 

(二)如果bean 中实体类导入的包是Java.sql包,则以学生类 student为例:

1、实体类中的日期set get方法各自的书写

 

2dao 中,添加add 方法中,关于日期的项 语句书写

 

3servlet中,

1)完成添加含有日期的数据的功能时, 从网页html或者jsp时,获取请求参数

 

String time=request.getParameter("birthday_day");

//假设网页上生日是通过input标签name="birthday_day"传入

//因为网页传过来的都是字符串,所以此句是一定的。

 

Student  student=new Student();

student.setBirthday(?);

StudentDao dao=new StudentDao();

dao.add(student);

2)完成根据条件查询数据,从数据库中查询到数据后的处理;

 StudentDao dao=new StudentDao();

 List<Student> list=dao.find();

//如果此处是将查询到的list作为结果返回到jsp界面

request.setAttribute("result",list);

request.getRequestDispatcher("index.jsp").forward(request,response);

4、 网页中

14 请求转发与重定向有何区别?

请求转发:服务器行为,request.getRequsetDispatcher().forward(requset,response);是一次请求,转发后请求对象会保存,地址栏的URL地址不会改变。(服务器内部转发,所有客户端看不到地址栏的改变)

 

重定向:客户端行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保持,地址栏的URL地址会改变。

 

(1) 地址栏中是否发生变化?

请求转发地址不改变

(2) 哪个可以携带请求参数?

请求转发可以携带

 

深入细解:

  HTTP中的重定向和请求转发的区别

 

一、调用方式

 

我们知道,在servlet中调用转发、重定向的语句如下:

 

request.getRequestDispatcher("new.jsp").forward(request, response);  

 //转发到new.jsp

 

response.sendRedirect("new.jsp");   //重定向到new.jsp

 

jsp页面中你也会看到通过下面的方式实现转发:

 

<jsp:forward page="apage.jsp" />

 

当然也可以在jsp页面中实现重定向:

 

<%response.sendRedirect("new.jsp"); %> //重定向到new.jsp

 

二、本质区别

解释一   一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:

转发过程:客户浏览器发送http请求——》web服务器接受此请求——》调用内部的一个方法在容器内部完成请求处理和转发动作——》将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

 

重定向过程:客户浏览器发送http请求——》web服务器接受后发送302状态码响应及对应新的location给客户浏览器——》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址——》服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

 

解释二

 

重定向,其实是两次request 第一次,客户端request   A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。

例子:

response.sendRedirect("loginsuccess.jsp");

 

请求转发是服务器内部把对一个request/response的处理权,移交给另外一个对于客户端而言,它只知道自己最早请求的那个A,而不知道中间的B,甚至CD。传输的信息不会丢失。

例子:

 

   RequestDispatcher dis=request.getRequestDispatcher(loginsuccess.jsp);

 

 Dis.forward(request,response);

 

解释三

 

假设你去办理某个执照

 

重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。

 

转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。

 

15 如何确定用请求转发还是重定向?

了解上述详细内容后,对于简单的问题,一般可遵循这个原则:

(1)在服务中,对于一般的查询性质的,用请求转发,其他的多数时候用重定向(到本服务,执行本servlet中的某个服务)

(2)如果需要传递参数,除了用户登录账号、密码等可以用cookieresponse.sendRedirect();request.getSession())进行设置,其他一般的用请求转发;

(3) 不需要传递参数的,一般为重定向;

16 页面转换,如何准确使用绝对路径和相对路径?

"/" 表示根目录,也就是项目中

"../" 表示到上一级目录

 

jsp页面中,为了防止因为绝对路径因文件移动等产生问题,一般都会使用相对路径,而不是绝对路径,基本上在所有的jsp的界面中都加入类似这种相对路径的引用语句,当然如下,还可以进行适当的修改

第一句利用请求对象request 获取当前路径的getContextPath();

第二句 request.getScheme() 返回当前链接使用的协议;比如,一般应用返回http;SSL返回https;

 

复习一下request 的常用方法:

request.getSchema()可以返回当前页面使用的协议,http或是 https;

request.getServerName()可以返回当前页面所在的服务器的名字;

request.getServerPort()可以返回当前页面所在的服务器使用的端口,就是80;

request.getContextPath()可以返回当前页面所在的应用的名字;

 

 

<%  

String path = request.getContextPath();

String basePath=request.getScheme()+"://"+request.getServerName()+":"+

                   request.getServerPort()+path+"/";

%>

而在<head></head>标签内部通过以下方式引用

<base href="<%=basePath%>">

 

17 如何修改tomcat配置,解决中文乱码问题?

 

在开发过程中,遇到中文乱码的问题。以前的解决办法是:用JAVA代码进行转换,今天请教了一下公司的高手,给出的解决方案是:修改Tomcat的配置文件也可以解决这个问题。

具体的解决方案是:

 

1.Tomcat目录下找到server.xml文件,找到代码:

 

<Connector port="80" protocol="HTTP/1.1"  connectionTimeout="20000"  redirectPort="8443" />

 

2. 把上面的代码注释掉,用下面的代码代替:

 

<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>

 

3. 注意Tomcat的端口号,我的Tomcat的端口品号是80,所以port="80"。请你修改成你自己的Tomcat的端口号。

 

18 如何修改eclipse或者myeclipse中的字符集问题?

 

打开windows——> preferences——>general——>workSpace

 

19 如何设置eclipse或者myeclipse中自动提示信息功能?

 

打开windows——> preferences——>Java——>editors

打开windows——> preferences——>xml——>editors

20 单元测试:

  注意:测试用例是用来达到测试想要的预期结果,而不能测试出程序的逻辑错误。

   ①测试方法上必须使用@Test进行修饰

   ②测试方法必须使用public void 进行修饰,不能带任何的参数

   ③新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开

   ④测试类所在的包名应该和被测试类所在的包名保持一致

   ⑤测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖

   ⑥测试类使用Test作为类名的后缀(不是必须)

   ⑦测试方法使用test作为方法名的前缀(不是必须)

 

        2.JUnit常用注解

        * @Test:将一个普通的方法修饰成为一个测试方法

              @Test(expected=XX.class)

              @Test(timeout=毫秒)

        * @BeforeClass:它会在所有的方法运行前被执行,static修饰

        * @AfterClass:它会在所有的方法运行结束后被执行,static修饰

        * @Before:会在每一个测试方法被运行前执行一次

        * @After:会在每一个测试方法运行后被执行一次

        * @Ignore:所修饰的测试方法会被测试运行器忽略

        * @RunWith:可以更改测试运行器 org.junit.runner.Runner

 

1.1 测试代码和项目代码分开

   结构应如下:包名要一致;最好以Test作为测试类后缀;最好以test作为测试方法前缀。

    Java中,一般是建立一个与src同层次的资源文件夹,命名为test在其中建立和src中一样的包名,并且建立和src中相应包下相同的类,只是鉴于习惯,会将这里的类名命名为在原类名基础上加个Test而已

     在测试类里,假设测试src文件夹下,com.examlple.dao包下 StudentDao类中的public int addStudent student),方法,则需要写的就是

      在项目中与src同层,建立一个test资源文件夹,其中建立一个com.example.dao包,在包中建立一个StudentDaoTest类, 类中写入

  @Test   //注解,必须写

   public void testadd(){    //方法必须以public void修饰,加方法名其中,不得带任何参数

       Student stu=new Student();    //因为被测试的方法需要一个参数

       stu.setid="小明";

       StudentDao dao=new StudentDao();      

       int abc=dao.add(stu);     

       Assert.assertEquals(3,abc);     //调用该方法 断言 第一个参数是预期值,第二个参数是实际测验值

  }

 

21 sql语句防注入如何做?

 

22 sql 基本语句:

原则:

---先在主表添加数据,再在子表添加数据

---先删除子表数据,再删除主表数据

 

查询语句:

-select<*|列名,...列名> from表名 where条件1 and条件2......

例:

select t.*, t.rowid from student t

select *from student

select name,id from student

select name "姓名",id as编号 from student

select * from student where id ='U003'--等值条件查询

select * from student where name like '%'--模糊查询,查询孙开头的

select * from student where name like '%%'

select * from student where name like '__'

select * from student where name like '__'and site like '222%'

select * from student where name like '__'or phone like '%888%'

select * from student where id='U002'or ID='u005'or id='U004'

select * from student where id in('U002','u005','U004')

添加语句:

nsert into 表名(字段名1,字段名2...,字段名n) values(参数值1,参数值2,...参数值n);

 

insert into student (id,name,age,phone,gender,email,site,address) values ('U010','李四',22,'44444','','444@qq.com','555.com','四海');

修改语句:

update 表名 set字段名1=参数值,字段名2=参数值,..where条件

 

update 表名 set字段名1=参数值,字段名2=参数值,..where字段名i=参数值i

 

update  student set name='111',phone='110' where name like '__'

 

删除语句:

delete from 表名 where条件;

 

delete from score where student_id='U001';

 

23

 

 

 

 

 

 


原创粉丝点击