动态Web 应用的基础代码。
关于IDE:最开始入门用Eclipse,但一用Idea 就立刻弃了Eclipse。Idea 相比来说更加智能,除了占内存多点以外,用Idea 体验超好,远超Eclipse。
关于Maven:学Maven 之前做项目都需要导Jar 包,比较麻烦而且可能有包版本冲突。有Maven 之后就爽多了!回不去了!它不仅用几行代码配置代替了导包的步骤,还会自动地导入很可能会用到的关联包,可节省不少时间。
1)上篇博文写的是静态页面,以下两图展示的是动态页面相关技术和基本流程。
2)Web Server - Tomcat: 是由 Apache 组织开发的一个 Servlet/JSP 容器(也就是负责解析和运行JSP),由纯 Java 开发完成的,若系统的负荷压力不是太大的话也可以兼作 Web 服务器(轻量级)。
Servlet 的Java 的、用来实现动态页面的 规范,由应用服务器(如Tomcat) 中的容器(Container) 来控制。
Tomcat 只支持J2EE 中的JSP以及Servlet规范,有的服务器支持更多规范,如WebLogic 和WebSphere 都支持J2EE 13种规范(EJB )。
当访问Tomcat 服务器的某个静态资源时,实际上在访问Tomcat 配置的缺省Servlet,url-pattern 为"/";
Tomcat 访问顺序:先找servlet, 没有的话执行缺省servlet 找静态资源,还没有的话返回404 等错误页面。
(预告:Struts2 框架就是一个大大的Servlet,会<load-on-startup>,提前初始化,1的优先级最高。)
访问tomcat出现java.lang.IllegalStateException No output folder错误解决方法
问题:tomcat分为安装版和解压缩版,解压缩版如果解压到安装盘,在浏览器中访问http://localhost:8080,可能会出现500错误,错误提示如下:
localhost:8080 java.lang.IllegalStateException: No output folder
原因如下:tomcat目录没有被读写的权限,导致文件不能被编译到指定的工作目录中。
解决办法:
找到tomcat目录,右键“属性--->安全--->编辑”,找到Users,将“完全控制”选项“允许”打钩,应用。
配置Tomcat (第5步项目创建后):菜单Run - Edit configurations - 左侧栏Defaults - Tomcat Server - Local, 设置Application Server 和Open browser,Apply,如下图;然后不用关此对话框,点左上角加号,添加Tomcat Server - Local - 设置Deployment,OK。
3)Servlet (Server Applet) 是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
4)开始用Idea 创建Maven 项目:File - New - Project... - Maven - Create from archetype (勾选上) - webapp - Next。如下图(第3步还有一个webapp 可选::org.apache.maven.archetypes:maven-archetype-webapp,这个模板更简单,需要新建java 和resources 文件夹;2.3版的web.xml 里很干净但2.4版之前是不支持EL表达式的,要换高版本或在jsp 页面加上"<%@page isELIgnored="false" %>";pom自带了junit dependency 依赖):
5)填写GroupId 和 ArtifactId,一路Next(其间可修改项目名称等),直到Finish,需等待Idea Run "Import change",完成后布局如下图(没有java 文件夹的话,新建一个,然后在其上右键 - Mark Directory As - Sources Root);
点击"Enable Auto-Import",这样每次修改Maven 的配置文件pom.xml,如添加依赖等,就会自动执行导入。
自动生成的web.xml 是2.4 版本,而且里面有些至少暂时用不到的servlet, listen 等配置,需要删掉。此模板应该可以修改的,尚未深究。
6)在pom.xml <plugins> 节点内添加以下插件代码,新建的选项就会出现Servlet、Filter、Listener 这三个。如果没有的话删除这段代码再贴上即可。添加servlet, mysql-connector, jstl 等依赖。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin>
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency>
另外Idea 不自动编译发布java 文件夹内的资源文件,在pom 配置中的build 标签内添加以下代码填上此坑:
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources>
7)创建前端页面;新建Servlet 实现类,Idea 会自动在web.xml 生成servlet 节点,但servlet-mapping(映射) 需要手动写上。
此Servlet 类继承了HttpServlet,重写父类的doGet() 和doPost() 方法(或Service() 方法),即可处理来自页面的Get 或Post 请求。注意它是没有主函数的,由Tomcat 内的容器调用才可运行。
<servlet> <servlet-name>UserServlet</servlet-name> <servlet-class>cn.rock.framework.controller.UserServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserServlet</servlet-name> <url-pattern>/UserServlet</url-pattern> </servlet-mapping>
8)Servlet 的执行过程
- Form 表单的action, a 标签的href 等可直接指向servlet 映射地址(即URL;也可指向静态页面资源),可用问号传参数,Form 表单input 标签内的name - value 参数一起打包提交;
- Tomcat Connector监听到浏览器发来的请求,解析出请求指向某个Servlet,然后把该请求交给它所在的Service的Container (Engine),Container 就会创建两个对象:1) HttpServletResponse 2) HttpServletRequest (存储页面提交过来的URL和参数);
- Container 根据request 传来的URL 找到正确匹配的servlet,为此request 创建或指定一个servlet 线程,并将request 和response 对象作为参数传给此servlet 线程;
- Container 调用此servlet 的servcie() 方法,service() 方法根据请求类型调用 doGet() 或 doPost() 方法;
- doGet() 或doPost() 可通过request.getParameter("name") 获取传来的参数,根据参数可分发请求、处理参数,与数据库交互,若有需要传给页面的信息,可用request.setAttribute("name", "value") 存到request.
- request 转发(多数情况下)或重定向到jsp 页面,jsp页面可用jstl 和EL 表达式展示动态数据。
- jsp 页面被存在response 对象,servlet 线程结束,Container 将response 对象转换为一个Http Response,发送给浏览器,并删除request 和response 对象。
9)创建数据库连接:
10)接第8条第5点,servlet 与数据库交互的具体过程:
- doGet() 或doPost() 方法调用Service接口(其实现类为ServiceImpl),ServiceImpl 调用Dao接口(其实现类为DaoImpl);
- JDBC(Java DataBase Connectivity):Java 操作数据库的技术,是一套接口标准,很好实现了面向接口编程,多态应用;
面向接口是面向对象的衍生。类似:电脑的USB 接口。
编程最重要的是可读性、可维护性、扩展性好,而不是功能。
底层思想基本都是封装、继承、多态。 - DaoImpl 直接与数据库交互:
String username = "root";
String password = "root";
String url = "jdbc:mysql://localhost:3306/mydb";//协议 ip 端口 数据库
String driver = "com.mysql.jdbc.Driver";//驱动
//1、加载数据库驱动 - 程序只要加载一次
Class.forName(driver);
//2、获取数据库的连接
Connection conn = DriverManager.getConnection(url, username, password);
//3、执行sql语句
//准备一条sql语句
String sql = "insert into student value(null, '小明', 20, 0, '1998-07-14', '计算机系', '北京市朝阳区')";
//通过connection获得Statement对象
Statement statment = conn.createStatement();
//statement对象传输sql语句
//如果是增删改 executeUpdate 返回值表示本次sql语句影响的行数
//如果是查 executeQuery
int result = statment.executeUpdate(sql);
System.out.println("sql语句执行的结果:" + result);
//4、关闭连接
statment.close();
conn.close();
11)至此,最基本的项目流程都过了一遍,之后就是在此基础上不断迭代升级。
12)升级1:提取数据库配置文件,在方法内处理异常、关闭资源,预处理sql 以避免sql 注入问题,提取数据库连接工具类。
配置文件(.properties .xml)作用:不需要编译,可由维护人员直接在项目运行时修改;只修改配置文件的内容就能全部修改为想要的数据。最主要的是不用修改代码,所以工作中配置文件往往比java代码还要多。
升级2:在ServiceImpl 层引入事务(即多条sql 作为一个逻辑单元,要么一起执行,要么都不执行),以满足现实需求。
升级3:使用 c3p0数据库连接池,更高效使用数据库连接。还有dbcp与druid 可选。
升级4:使用过滤器Filter,可过滤页面、统一编码等。(监听器Listener 目前作用不大)
升级5:JavaScript 的Ajax 局部刷新技术,通过Ajax Engine 获取xml 数据, 现在多用json;使用JQuery 比原生JS 要高效得多。
<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
<script>
$(function () {
$("input").blur(function () {
var value = $(this).val();
if ($.trim(value) == "") {
alert("Username can't be void");
return;
}
/*$.get("RegisterServlet", {"username": value}, function (data) {
if (data == 0) {
$("input").next().html("Yes");
} else {
$("input").next().html("No");
}
});*/
$.ajax({
url: "RegisterServlet",
data: {username: value},
success: function (data) {
if (data == 0) {
$("input").next().html("Yes");
} else {
$("input").next().html("No");
}
}
})
});
//ajax to submit form
$("button").click(function () {
$.ajax({
type: "post",
url: $("form").attr("action"),
data: $("form").serialize(),
success: function () {
}
});
});
});
</script>