day09
-
综合项目实战
-
项目描述
1.项目描述
利用JavaWeb阶段所学的技术,如html、css、Servlet、JSP、el、JSTL、JDBC等技术实现电商项目(京淘jt)中后台管理系统的商品管理模块。实现商品添加、商品列表、商品删除、商品修改等功能。
2.环境搭建
-
创建工程
创建一个动态web工程
2.导入jar包
资源寻贴主要
导入工程中所需的jar包和配置文件
1.导入jar包(放在工程的/WEB-INF/lib目录下!!!)
2.导入配置文件(放在src目录下!!!)
3.组织工程目录结构
1.创建包结构
(1)在src下创建com.tedu.jt.utils包和com.tedu.jt.web.backend包
(2)在WebContent目录下,创建backend目录用来存放项目中的jsp页面
4.导入页面
将课程资料中提供的静态页面导入工程中
资源寻贴主要
1.静态页面
2.导入工程
在工程的/WebContent/backend目录下创建对应的jsp页面,例如:manage.html à manage.jsp
3.修改页面代码
(1)修改manage.jsp
4.测试访问
3.代码实现_1_商品添加
-
商品添加入口开发
1.入口开发:编辑_left.jsp页面,修改”商品添加”链接地址,点击商品添加跳转到prod_list.jsp页面。
2.编辑prod_add.jsp页面,修改商品添加表单提交地址,提交表单访问ProdAddServlet来处理添加商品请求。
2.商品添加后台实现
1.创建ProdAddServlet,用于处理客户端的添加商品请求
2.导入JDBCUtils工具类
提示: JDBCUtils工具类代码实现参见本文档<<1.7.1>>章节
package com.tedu.jt.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
importcom.mchange.v2.c3p0.ComboPooledDataSource;
/**
* JDBC工具类
*/
public class JDBCUtils {
/**
* 2.创建c3p0连接池实例
*/
private static ComboPooledDataSource pool
= new ComboPooledDataSource();
/**
* 1.私有化构造函数
*/
private JDBCUtils() {}
/**
* 3.提供getConn方法, 用于从连接池中获取一个连接对象
* @return Connection 连接对象
* @throws Exception
*/
public static Connection getConn() throws Exception {
try {
return pool.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}
/**
* 4.提供close方法, 用于释放资源
* @param conn 连接对象
* @param ps 传输器对象
* @param rs 结果集对象
*/
public static void close(Connection conn, Statement stat,
ResultSet rs) {
if(rs != null ){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
if(stat != null ){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
stat = null;
}
}
if(conn != null ){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
3.设计表结构
-- 0.删除jt_db数据库(如果存在)
drop database if exists jt_db;
-- 1.创建数据库jt_db
create database jt_db;
-- 2.选中jt_db数据库
use jt_db;
-- 3.在 jt_db 库中创建product表(商品表)
create table product(
id int primary key auto_increment, -- 商品ID
name varchar(50), -- 商品名称
category varchar(50), -- 商品分类
price double, -- 商品单价
pnum int, -- 库存数量
description varchar(50) -- 商品描述
);
4.实现ProdAddServlet,处理商品添加请求
(1)实现ProdAddServlet的doGet方法
package com.tedu.jt.web.backend;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tedu.jt.utils.JDBCUtils;
/**
* Servlet implementation class ProdAddServlet
*/
public class ProdAddServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ProdAddServlet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 0.处理乱码(如果添加了过滤器处理乱码,这里不要重复处理!)
// >>请求参数乱码
request.setCharacterEncoding("utf-8");
// >>响应正文乱码
response.setContentType("text/html;charset=utf-8");
// 1.获取商品信息
String name = request.getParameter("name");
String category = request.getParameter("category");
Double price = Double.parseDouble(request.getParameter("price"));
int pnum = Integer.parseInt(request.getParameter("pnum"));
String description = request.getParameter("description");
// 2.将商品信息存入数据库中
addProd(name,category,price,pnum,description);
// 3.提示用户商品添加成功.
response.getWriter().write("<h1 style='color:red;text-align:center'>");
response.getWriter().write("商品添加成功!");
response.getWriter().write("</h1>");
// 4.定时刷新到ProdListServlet, 查询商品列表
response.setHeader("Refresh", "3;url="+request.getContextPath()+"/ProdListServlet");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(2)在ProdAddServlet中添加addProd方法用于将商品信息保存到数据库中,代码实现如下:
private void addProd(String name, String category, Double price, int pnum, String description) {
Connection conn = null;
PreparedStatement ps=null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConn();
// 2.声明sql语句
String sql = "insert into product values(null,?,?,?,?,?)";
// 3.获取传输器
ps = conn.prepareStatement(sql);
ps.setString(1, name);
ps.setString(2, category);
ps.setDouble(3, price);
ps.setInt(4, pnum);
ps.setString(5, description);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println("商品添加失败");
}finally {
JDBCUtils.close(conn, ps, rs);
}
}
5.测试:添加一个商品,查看数据中的product表中,是否具有新增的商品记录(略)
4.代码实现_2_商品列表
-
商品列表入口开发
1.入口开发:编辑_left.jsp中”商品管理”超链接,点击连接访问ProdListServlet查询所有商品信息.
2.商品列表后台实现
创建ProdListServlet,查询所有商品信息,将商品信息封装到Product对象中,并将所有商品存入list集合中,存入到request域中转发到prod_list.jsp中展示.
1.创建ProdListServlet
2.创建Product类,用于表示商品信息
提示: Product类实现参见本文档<<1.7.2>>章节
3.实现ProdListServlet类
(1)实现ProdListServlet中的doGet方法
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.查询所有的商品信息
List<Product> list = findProList();
//2.将list集合存入request域中
request.setAttribute("list", list);
//3.通过转发将所有的商品信息带到jsp中展示
request.getRequestDispatcher("/backend/prod_list.jsp").forward(request, response);
}
(2)在ProdListServlet中添加findProdList方法用于查询所有的商品信息,代码实现如下:
/**
* 查询所有的商品信息, 作为list集合返回
* @return List<Product>
*/
private List<Product> findProList() {
Connection conn =null;
PreparedStatement ps=null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConn();
String sql = "select * from product";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
List<Product> list = new ArrayList<Product>();
while(rs.next()) {
Product product = new Product(rs.getInt("id"),
rs.getString("name"),
rs.getString("category"),
rs.getDouble("price"),
rs.getInt("pnum"),
rs.getString("description"));
list.add(product);
}
System.out.println("list:"+list);
return list;
} catch (Exception e) {
e.printStackTrace();
System.out.println("商品查询失败!");
}finally {
JDBCUtils.close(conn, ps, rs);
}
return null;
}
3.商品列表页面实现(prod_list.jsp)
在ProdListServlet中将会查询出所有商品信息,存入List集合并将List集合存入request域中,通过转发带到prod_list.jsp页面,在prod_list.jsp中通过JSTL标签(c:forEach)取出集合中的数据进行展示.
1.编辑prod_list.jsp,使用EL+JSTL遍历List集合中的商品信息
(1)通过taglib指令导入JSTL标签库
<%@ page language="java"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
(2)使用EL+JSTL遍历商品信息
<!-- 遍历集合 -->
<c:forEach items="${list}" var="prod">
<tr>
<td>${prod.id }</td>
<td>${prod.name }</td>
<td>${prod.category }</td>
<td>${prod.price }</td>
<td>
${prod.pnum }
</td>
<td>${prod.description }</td>
<td>
<a id="delProd" href="#">删除</a> |
<a id="updProd" href="prod_update.html">修改</a>
</td>
</tr>
</c:forEach>
2.测试: 点击商品管理查询所有商品信息(略)编辑_left.jsp
<body margin="0">
<div id="menu_bar">
<div><a href="${pageContext.request.contextPath}/ProdListServlet" target="rightFrame">> 商品管理</a></div>
<div><a href="prod_add.jsp" target="rightFrame">> 商品添加</a></div>
</div>
</body>
5.代码实现_3_商品修改
-
商品修改入口开发
1.入口开发:编辑prod_list.jsp中”修改”超链接,点击“修改”连接,访问ProdUpdServlet,根据商品ID查询商品信息.
2. 商品修改后台实现_1(ProdServlet)
创建ProdServlet,根据商品ID查询商品信息,并将商品信息存入request域通过转发将商品信息带到prod_upd.jsp回显
1.创建ProdServlet
2.实现ProdServlet
(1)实现ProdServlet的doGet方法
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//获取商品id
int pid = Integer.parseInt(request.getParameter("pid"));
//根据商品id查询商品信息
Product prod = findProdById(pid);
//将商品信息存入request域中
request.setAttribute("prod", prod);
//4通过转发将商品信息带到prod_update.jsp进行修改
request.getRequestDispatcher("/backend/prod_upd.jsp").forward(request, response);
}
(2)在ProdServlet中添加findProdById方法并实现,如下:
/**
* 根据商品id查询商品信息
* @param pid
* @return
*/
private Product findProdById(int pid) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConn();
String sql ="select * from product where id=?";
ps = conn.prepareStatement(sql);
ps.setInt(1, pid);
rs = ps.executeQuery();
Product product =null;
if(rs.next()) {
product = new Product(
pid,
rs.getString("name"),
rs.getString("category"),
rs.getDouble("price"),
rs.getInt("pnum"),
rs.getString("description"));
}
return product;
} catch (Exception e) {
e.printStackTrace();
System.out.println("根据Id查询数据失败!");
}finally {
JDBCUtils.close(conn, ps, rs);
}
return null;
}
3.商品修改页面实现(prod_upd.jsp)
在ProdServlet中将会查询出所要修改的商品信息,存入request域中,通过转发带到prod_upd.jsp页面,在prod_upd.jsp中通过EL取出集合中的数据进行回显,供用户修改.
1.编辑prod_upd.jsp,通过el表达式取出所要修改的商品信息
<form action="${pageContext.request.contextPath}/ProdUpdServlet" method="POST">
<input type="hidden" name="id" value="${prod.id}"/>
<table border="1">
<tr>
<td width="30%">商品名称</td>
<td>
<input type="text" name="name" value="${prod.name}"/>
</td>
</tr>
<tr>
<td>商品种类</td>
<script>
window.onload = function(){
//1.获取select元素
var sele = document.getElementsByName("category")[0];
//2.通过select元素获取data属性值(如:家用电器)
var data = sele.getAttribute("data");
//3.获取所有的option选项,循环遍历,取出每一个option
var opt = document.getElementsByTagName("option");
//>>获取当前被遍历的option标签内的文本
var optlen = opt.length;
//>>将data属性的值和option标签内的文本进行比较
for(var i =0;i<optlen;i++){
if(data == opt[i].innerHTML){
//>>如果相等则将该选项设置为默认被选中
opt[i].setAttribute("selected",true);
return;
}
}
}
</script>
<td>
<select name="category" data="${prod.category}">
<option>手机数码</option>
<option>电脑平板</option>
<option>家用电器</option>
<option>汽车用品</option>
<option>食品饮料</option>
<option>图书杂志</option>
<option>服装服饰</option>
<option>理财产品</option>
</select>
</td>
</tr>
<tr>
<td>商品单价</td>
<td>
<input type="text" name="price" value="${prod.price}"/>
</td>
</tr>
<tr>
<td>库存数量</td>
<td>
<input type="text" name="pnum" value="${prod.pnum }"/>
</td>
</tr>
<tr>
<td>商品描述</td>
<td>
<textarea name="description">${prod.description}</textarea>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="修改商品信息" />
</td>
</tr>
</table>
</form>
2.编辑prod_upd.jsp,修改”修改商品信息”表单的提交地址.
4.商品修改后台实现_2(ProdUpdServlet)
创建ProdUpdServlet,修改指定ID的商品信息,修改完后定时刷新到ProdListServlet查询所有商品信息.
1.创建ProdUpdServlet.
2.实现ProdUpdServlet.
(1)实现ProdUpdServlet中的doGet方法.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
String category = request.getParameter("category");
Double price = Double.parseDouble(request.getParameter("price"));
int pnum = Integer.parseInt( request.getParameter("pnum"));
String description = request.getParameter("description");
UpdProdById(id,name,category,price,pnum,description);
// 3.提示用户商品添加成功.
response.getWriter().write("<h1 style='color:red;text-align:center'>");
response.getWriter().write("商品修改成功!");
response.getWriter().write("</h1>");
// 4.定时刷新到ProdListServlet, 查询商品列表
response.setHeader("Refresh", "3;url="+request.getContextPath()+"/ProdListServlet");
}
(2)在ProdUpdServlet中添加updProdById方法并实现,如下:
/**
* 更新数据库中的数据
* @param id
* @param name
* @param category
* @param price
* @param pnum
* @param description
*/
private void UpdProdById(int id, String name, String category, Double price, int pnum, String description) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConn();
String sql ="update product set name=?,category=?,price=?,pnum=?,description=? where id="+id;
ps = conn.prepareStatement(sql);
ps.setString(1,name);
ps.setString(2,category);
ps.setDouble(3, price);
ps.setInt(4, pnum);
ps.setString(5, description);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println("修改数据失败");
}finally {
JDBCUtils.close(conn, ps, rs);
}
}
6.代码实现_4_商品删除
-
商品删除入口开发
1.入口开发,编辑prod_list.jsp中”删除”超链接,点击连接,访问ProdDelServlet删除指定ID的商品信息.
2.商品删除后台实现
创建ProdDelServlet,根据请求参数中的商品ID删除指定ID的商品记录. 删除后定时刷新到ProdListServlet查询所有商品信息.
1.创建ProdDelServlet
2.实现ProdDelServlet,根据商品ID删除商品
(1)实现ProdDelServlet中的doGet方法.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获取前端传来的删除商品的id
int pid = Integer.parseInt(request.getParameter("pid"));
//根据id删除数据
delProdById(pid);
// 3.提示用户商品添加成功.
response.getWriter().write("<h1 style='color:red;text-align:center'>");
response.getWriter().write("商品删除成功!");
response.getWriter().write("</h1>");
//注意:不能直接去转发到/backend/prod_list.jsp页面因为直接转发过去没有携带查询出的数据所以无法显示
// 所以要到ProdListServlet中取数据显示
// 4.定时刷新到ProdListServlet, 查询商品列表
response.setHeader("Refresh", "3;url="+request.getContextPath()+"/ProdListServlet");
//转发到查询页面(商品列表页面)
}
(2)在ProdDelServlet中添加delProdById方法并实现,如下:
/**
* 根据ID删除商品
*/
private void delProdById(int pid) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs =null;
try {
//获取的链接
conn = JDBCUtils.getConn();
String sql = "delete from Product where id=?";
ps = conn.prepareStatement(sql);
ps.setInt(1, pid);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn, ps, rs);
}
}
7.代码实现_5_细节处理
-
JDBCUtils工具类实现
1.私有化构造函数、创建c3p0连接池实例
2.提供getConnection方法,用于从连接池中获取一个连接对象
3.提供close方法,用于释放资源(其中调用conn.close()是将连接还回连接池中而不是关闭连接)。
2.Product(商品类)实现
1.创建商品类,添加如下成员
2.为成员变量提供对应的setter和getter方法
3.异常处理
问题描述: 当商品的添加、查询、删除、修改成功后会提示“商品添加、查询、修改、删除成功!”,但是如果操作失败了,还是会提示“xxx成功”,但其实应该提示“xxx失败”的信息。
解决方案:
1、在web.xml文件中为整个项目的异常信息配置友好错误提示页面,当抛出异常时,不要给用户显示提示异常信息的页面,而是提示友好错误提示页面. 配置如下:
<error-page>
<error-code>500</error-code>
<location>/backend/500.jsp</location>
</error-page>
2、修改Servlet中针对异常抛出时处理的代码:
(1)在ProdAddServlet中的addProd方法中, 修改如下:
(2)在ProdListServlet中的findProdList方法中, 修改如下:
(3)在ProdInfoServlet中的findProdById方法中, 修改如下:
(4)在ProdUpdServlet中的updProdById方法中, 修改如下:
(5)在ProdDelServlet中的delProdById方法中, 修改如下:
8.MVC设计模式
MVC设计模式: 通用的软件编程思想, 在MVC设计模式中认为, 任何软件都可以分为:控制程序流转的控制器(Controller)、封装数据处理数据的模型(Model)、负责展示数据的视图(view)三部分组成。并且在MVC设计思想中要求一个符合MVC设计思想的软件应该保证上面这三部分相互独立,互不干扰,每一个部分只负责自己擅长的部分。如果某一个模块发生变化,应该尽量做到不影响其他两个模块。这样做的好处是,软件的结构会变得更加的清晰,可读性强。有利于后期的扩展和维护,并且代码可以实现复用。
day10
修改prod_upd.jsp页面使下拉框在修改商品信息时自动选中商品的种类。
<script>
/* 定义一个文档就绪事件, 在整个页面加载完之后再
获取页面中的元素或属性 */
window.onload = function(){
//1.获取select元素
var oSele = document
.getElementsByName("category")[0];
//2.通过select元素获取data属性值(如:家用电器)
var category = oSele.getAttribute("data");
alert(category);
//3.获取所有的option选项,循环遍历,取出每一个option
var arrOpt = oSele.getElementsByTagName("option");
var len = arrOpt.length;
for(var i=0;i<len;i++){
//>>获取当前被遍历的option标签内的文本
//>>将data属性的值和option标签内的文本进行比较
if(category == arrOpt[i].innerHTML){
//>>如果相等则将该选项设置为默认被选中
arrOpt[i].setAttribute(
"selected", true);
return;
}
}
}
</script>
<td>
<select name="category" data="${ prod.category }">
<option>手机数码</option>
<option>电脑平板</option>
<option>家用电器</option>
<option>汽车用品</option>
<option>食品饮料</option>
<option>图书杂志</option>
<option>服装服饰</option>
<option>理财产品</option>
</select>
</td>
六.商品修改功能实现
1.入口开发
修改prod_list.jsp中修改超链接的地址, 改为访问 ProdInfoServlet
<a id="updProd" href="${ pageContext.request.contextPath }/ProdInfoServlet?id=${prod.id}">修改</a>
2.后台开发: 创建一个ProdInfoServlet, 并实现根据商品ID查询商品信息
//1.获取商品的id
//2.根据ID查询商品信息
//3.将商品信息(对象)存入request域中
//4.通过转发将商品信息带到商品修改页面, 进行展示
3.编辑prod_upd.jsp, 在这个jsp中取出要修改的商品信息(数据回显), 可以在原有信息的基础上进行修改
4.修改prod_upd.jsp中form表单的提交地址, 将地址改为访问ProdUpdServlet.
<form action="${pageContext.request.contextPath}/ProdUpdServlet" method="POST">
5.创建ProdUpdServlet, 并实现商品修改功能
//0.处理乱码
//>>请求参数乱码
//>>响应正文乱码
//1.获取修改后的商品信息
//2.根据商品ID修改商品信息
//3.提示用户商品修改成功
//4.3秒跳转到商品列表页面(ProdListServlet --> prod_list.jsp).
七.MVC设计模式
M: Model 模型
V: View 视图
C: Controller 控制器
Servlet: 本质上是一段Java程序, 非常适合来处理逻辑, 不太合适响应一个完整的HTML网页
HTML: 非常合适用来开发网页, 也适合用于展示数据, 但是HTML开发出来的网页本质上是一个文档, 不能用于展示动态的数据
JSP: 看起来非常像一个HTML, 可以用于开发网页, 也可以展示数据, 又因为JSP本质上是一个Servlet, 所以可以展示动态的数据.
只用JSP开发软件
JSP接收请求
JSP获取数据
JSP处理请求(需要和数据库进行交互)
JSP展示处理的结果
如果将所有的代码(HTML代码,Java代码)都写在一个JSP中, JSP页面的结构就会变得特别的混乱, SUN在JSP2.0版本中推荐不要在JSP中写任何一行Java代码
可以使用EL和JSTL标签来取代大部分的Java代码.
Servlet: 接收请求, 控制请求的流转, 处理请求(需要和数据库进行交互)
JavaBean: Product(封装数据 实体Bean) ProdService (处理业务逻辑 业务Bean)
JSP:展示结果
JavaEE的经典三层架构
表示层(WEB层): Servlet+JSP 直接和用户进行交互
业务逻辑层(Service层): service 处理业务逻辑
数据访问层(持久层 Dao层): 直接和数据库进行交互
一.相对路径和绝对路径(推荐使用绝对路径!!)
相对路径: 不以斜杠( / )开头的路径, 比如: 1.jpg a/1.jpg
./1.jpg ../1.jpg (相对路径不稳定!!!)
绝对路径: 以斜杠开头的路径, 不如: /day20/1.jpg /day20/a/1.jpg
复习和总结day01
相对路径:
(1)第一次访问: 直接访问1.html -->
http://localhost:8080/day20/a/1.html
在1.html中引入1.jpg图片, 如下:
<img src="1.jpg" width="400" height="300"/>
1.html的路径为:
http://localhost:8080/day20/a/1.html
1.jpg的路径(由1.html所在的路径+相对路径)
http://localhost:8080/day20/a/1.jpg
(2)第二次访问: 访问TestServlet, 通过转发访问1.html
1.html的路径为:
http://localhost:8080/day20/TestServlet 1.html
1.jpg的路径(由1.html所在的路径+相对路径)
http://localhost:8080/day20/1.jpg
绝对路径:
<img src="/day20/a/1.jpg" width="400" height="300"/>
http://localhost:8080/day20/a/1.jpg 对的
在写路径时, 什么时候加上当前WEB应用的虚拟路径, 什么时候不加?
请求转发时:
request.getRequestDispatcher("/BServlet").for...
请求包含时:
(1)通过request实现:
request.getRequestDispatcher("/BServlet").inc...
(2)通过include指令实现:
<%@include fil="/b.jsp"%>
请求转发和包含比较特殊, 因为请求转发和包含只能转发到或者是包含同一个WEB应用内部的资源, 所以服务器会自动为我们拼接上WEB应用的虚拟路径. 所以这两处在写路径时, 可以不用加上 WEB应用的虚拟路径.
请求重定向时:
response.sendRedirect("/day20/index.jsp");
定时刷新时:
response.setHeader("Refresh","3;url=/day20/index.jsp");
包含一个css文件时:
<link href="/day20/css/index.css"/>
包含一个js文件时:
<script src="/day20/js/index.js"></script>
包含一个图片时:
<img src="/day20/a/1.jpg"/>
表单的提交地址:
<form action="/day20/TestServlet"></form>
在写WEB应用的虚拟路径时, 如果可以通过Java代码动态获取, 请不要写死!!!
day11
复习和总结day02
day01/day02-------------
1.JDBC概述
1.1.什么是JDBC
利用Java语言操作数据库的一门技术
1.2.为什么要学习JDBC
更多的是通过程序(Java)来操作数据库, 如果使用Java程序操作数据库, 就需要学习JDBC.
1.3.如何使用JDBC开发数据库程序
1.导入MySQL的驱动包
2.创建类
//1.注册驱动
//2.获取数据库连接
//3.获取传输器
//4.利用传输器发送sql到数据库执行, 返回执行结果
//5.处理结果
//6.释放资源
2.JDBC API
2.1.注册驱动
DriverManager.registDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");
2.2.获取连接
DriverManager.getConnection(url, user, password);
DriverManager.getConnection(url);
url的写法:
jdbc:mysql://localhost:3306/jt_db?user=root&password=root
简写形式:
jdbc:mysql:///jt_db...
http://localhost:8080/day18/index.jsp?username=zs&password=123
2.3.获取传输器
Statement stat = conn.createStatement();
PreparedStatement ps = conn.prepareStatement(sql);
2.4.获取结果集
executeQuery() --- ResultSet 查询
executeUpdate() --- int 更新
2.5.释放资源
rs.close()
stat.close()
conn.close()
finally{}
3.JDBC的增删改查
4.JDBCUtils工具类
conf.properties
drvierClass=
jdbcUrl=
user=
password=
public class JDBCUtils{
private JDBCUtils(){
}
static{
Properties prop = new Properties();
}
public static Connection getConnection(){
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url,user, password);
return conn;
}
public static void close(){
}
}
5.PreparedStatement
Statement
1.防止sql注入攻击
2.效率高
3.省去拼接sql参数的麻烦
模拟登陆的例子
SQL注入攻击: # '' or and 会导致SQL语句语义的改变
6.批处理
批处理是用于将大量的sql一次性发送到数据库执行的一门技术
批处理实现方式
(1)通过statement对象实现批处理
(2)通过preparedStatement对象实现批处理
7.数据库连接池
7.1.什么是连接池?
线程池, 常量池 池: 容器
将连接放在池子中(容器), 在整个程序中共享.
.
7.2.为什么要使用连接池?
将连接放在池子中(容器), 在整个程序中共享.
可以实现连接的复用
可以减少连接开和关的次数
7.3.如何自定义连接池
public class MyPool implement DataSource{
}
7.4.开源数据库连接池
dbcp c3p0
如何使用c3p0
(1)导入c3p0的开发包
(2)在src或者相似的目录下,提供一个c3p0-config.xml文件
(3)创建一个连接池对象
ComboPooledDateSource pool = new ComboPooledDateSource();
pool.getConnection();
(4)conn.close();//还连接
继承
A close a
B close b
装饰者模式
通过对对象的包装来扩展对象功能的一种模式
//字节流, 一次读一个字节
InputStream in = new FileInputStream();
//字符流, 一次读一个字符
InputStreamReader isr = new InputStreamReader(in);
//带缓冲区的字符流, 一次可以读一串
BufferedReader br = new BufferedReader(isr)
MyBatis: 简化JDBC
Hibernate: 简化JDBC代码
day03/day04-------------
基于HTTP协议的WEB服务端程序
利用前面JavaSE所学的知识(Socket, 线程池, IO流, xml) HTTP协议 JDBC
(1)对前面所学的知识做一个复习巩固
(2)为后面对tomcat服务器的学习和使用打下基础
(3)了解浏览器和服务器之间的通信协议 --- HTTP协议
day05/day06/day07-------------
HTML
1.HTML概述
1.1.什么是HTML
超文本标记语言, 是用来开发网页的最基础的语言
1.2.HTML结构
<!doctype html> html5.0
<html></html>
<head></head>
<body></body>
<title></title>
<meta charset="utf-8"/>
1.3.HTML语法
标签, 自闭标签 <input /> <img /> <br/> <hr/>
属性
注释: <!-- 注释内容 -->
换行: <br/>
空格:
1.4.HTML和xml的区别
相同点: 都是标记语言, 都是通过标记来组织文档结构
不同点:
html中的标签都是提前定义好的, 不允许自定义
xml中的标签允许用户自己定义
html对语法要求非常不严格
xml对语法要求非常严格
2.HTML标签
2.1.标题
h1~h6
2.2.列表
ul li 无序列表
ol li 有序列表
2.3.图像标签
<img src="图像的路径" width="" height="" alt=""/>
2.4.超链接标签
<a href="http://www.baidu.com" target="以何种方式打开超链接">百度一下</a>
_self
_blank
frameName
2.5.表格标签
table -- 定义一个表格
border: 边框
cellspacing
cellpadding
padding
bgcolor
bordercolor
width
align
tr -- 定义表格行
align
bgcolor
td -- 定义单元格
align
bgcolor
width
height
colspan
rowspan
th -- 定义表头
caption -- 标题
2.6.表单标签
<form action="表单的提交地址" method="提交方式"></form>
表单的作用: 向服务器发送数据
超链接也可以向服务器发送数据
GET/POST: 只有使用表单并且明确的指定了使用POST才是post提交, 其他方式都是GET提交
2.7.表单项标签
input
普通文本输入框:<input type="text" name="username"/>
密码输入框:<input type="password" name="password"/>
单选框:<input type="radio" name="gender"/>男
复选框:<input type="checkbox" name="like"/>
文件上传项:<input type="file" name="photo"/>
提交按钮:<input type="submit" value=""/>
重置按钮:<input type="reset" value=""/>
普通按钮:<input type="button" value=""/>
select
<select name="city">
<option>北京</option>
<option>北京</option>
<option>北京</option>
</select>
textarea
<textarea>请输入描述信息...</textarea>
2.8.其他标签
div,span,p 看作是一个容器, 用来包裹其他的html内容
块级元素: 默认情况下, 独占一行
可以设置宽高
外边距/边框/内边距都可以设置
行内元素: 默认情况下, 多个元素可以处在同一行
不可以设置宽高
左右外边距/边框/内边距都可以设置
CSS
1.CSS概述
1.1.什么是CSS
层叠样式表, 用于美化网页的一门技术
可以实现将展示数据的html代码和设置样式的CSS代码进行分离
2.引入CSS
2.1.标签上的style属性
<div style="color:red;background-color:blue">
2.2.通过style标签引入CSS
<style>
span{
font-size:20px;
}
</style>
2.3.通过link引入外部的css文件
在html中
<link href="demo.css"/>
在css文件中(demo.css)
p{
....
}
3.CSS选择器
基本选择器
(1)标签名选择器, 比如: span{..}
(2)类选择器,
.c1{...}
(3)ID选择器
#d1{...}
扩展选择器
(1)后代: div span{..}
(2)子元素: div>span{..}
(3)分组: div,span,p{..}
(4)属性: div[name='div1']{..}
(5)相邻兄弟选择器: div+p{}
(6)伪元素
div:{background-color:red}
div:hover{background-color:green}
4.盒子模型
margin:10px 20px 30px 40px;
margin:10px 20px 30px;
margin:10px 20px;
margin:10px;
border:1px solid red;
border-width:
border-style:
border-color:
padding:10px 20px 30px 40px;
5.常用的CSS属性
5.1.display 设置元素是否显示以及如何显示
block 块级元素
inline 行内元素
inline-block 行内块元素
none 隐藏元素
5.2.文本属性
text-align
text-indent
letter-spacing
text-shadow
text-decoration
5.3.字体属性
font-size
font-weight
font-family
color
line-height
5.4.背景属性
background-color
background-image
background-repeat
background-position
京淘后台管理页面
注册页面
day08/day09/day10/day11-------------
JS
1.JS概述
1.1.什么是JS
基于对象和事件驱动的脚本语言, 专门为网页交互而设计
1.2.JS的特点
解释执行, 不需要编译
基于对象
弱类型
var i ="";
i = 100;
1.3.JS的优势
交互性
安全性
跨平台性
1.4.引入JS
(1)在script标签内部直接书写JS代码
(2)通过script标签引入外部的JS文件
2.JS语法
2.1.注释 // /* */
2.2.数据类型
基本数据类型:
number、string、boolean、undefined、null
在JS中数值类型在底层都是浮点型
字符串是基本数据类型, 常量可以用单引号或双引号引起来
复杂数据类型:
对象(数组、函数、对象)
2.1.变量和运算符
var声明变量 变量不区分类型, 可以指向任意的数据类型
大致和Java中的运算符相同
=== : 不会作类型的转换, 直接比较, 如果类型不相同直接返回false
typeof: 返回变量或表达式的数据类型
delete: 删除数组中的元素或者删除对象上的属性或方法
2.1.语句
大致和Java中的语句相同
if...else...
switch...case
for(){}
while(){}
区别在于如果判断条件或者循环条件不是布尔类型, 会自动转为布尔类型.
2.1.数组
var arr1 = new Array();
var arr2 = new Array(10);
var arr3 = new Array(10,44,"abc");
var arr4 = [];
var arr4 = [10,44,"abc"];
2.1.函数
function 函数名称([参数列表]){
函数体
...
}
函数名称([参数列表]);
var 函数名称 = function ([参数列表]){
函数体
...
}
函数名称([参数列表]);
2.1.对象
(1)JS的内置对象
正则表达式对象 RegExp test ig
字符串对象 String match
日期对象 Date
var date1 = new Date();
var date2 = new Date(时间毫秒值);
var date3 = new Date(2018,2,23, 11, 9, 11);
toLocaleString()
getFullYear()
getMonth()
getDate()
getDay()
Math
PI属性
ceil
round
floor
Global
parseInt
parseFloat
isNaN
eval
(2)自定义对象
function Person(){}
var p1 = new Person();
p2 = {
"name":"zs",
"age" : 18
}
DHTML
1.DHTML概述
1.1.什么是DHTML
DHTML: 动态的HTML, 利用JS可以操作页面中的元素或者是样式
HTML、CSS、JS整合在一起, 形成了DHTML技术
1.2.DHTML工作原理
将所有的HTML元素使用JS对象进行表示
通过对象来表示元素本身, 使用对象之间的包含关系来表示元素和元素之间的层级关系
通过一个文档结构树表示整个HTML文档
在对象上设计属性或者方法, 通过操作对象上的属性或方法, 来间接操作元素的属性或行为
1.3.BOM+DOM
BOM: 浏览器对象模型(和浏览器相关的对象, window/location)
DOM: 文档对象模型(和HTML文档相关的对象, document,body)
1.2.BOM
window
alert方法
confirm方法
onload事件
location
href
window.location.href
window.location.href = "${ pageContext.request.contextPath }/ProdDelServlet";
1.3.DOM
获取元素
var obj = document.getElementById("xx");
var arr1 = document.getElementsByName("xx");
arr1[0]
arr1[1]
var arr2 = document.getElementsByTagName("div");
arr2[0]
arr2[2]
obj.value
div.innerHTML
div.innerText
obj.value = "";
div.innerHTML = "";
div.innerText = "";
增删改元素
创建元素:
var obj = document.createElement("div");
添加元素:
parentEle.appendChild(child);
插入元素:
parentEle.insertBefore(new, child);
删除元素
parentEle.removeChild(child)
替换元素
parentEle.replaceChild(new, child)
复制克隆元素
ele.cloneNode([true/false])
document.body
ele.parentNode
oDiv.style.display = "none";
oInp.checked; //true | false
oInp.checked = "true | false"
jQuery
1.概述
1.1.什么是jQuery
jQuery: JS查询
轻量的、免费开源的JS函数库, 可以极大简化JS代码。
1.2.jQuery的优势
极大简化JS代码
可以像CSS那样获取页面元素
可以通过操作CSS属性控制页面的样式
可以兼容大部分的浏览器
...
1.3.jQuery版本
1.x --- IE6+和常用的浏览器
2.x --- IE9+和常用的浏览器
3.x --- IE9+和常用的浏览器
jQuery高版本不兼容低版本
1.4.jQuery引入
<script src="../js/jquery-1.4.2.js"></script>
2.jQuery语法
2.1.$
$ == jQuery
$() == jQuery() 调用函数返回一个jQuery对象, 这个jQuery对象中包含了若干HTML元素, 可以通过jQuery提供的方法操作这些元素
var $oDiv = $("#div1")
$oDiv.css({
"color":"red",
"width" : "200px"
});
2.2.文档就绪事件函数
ready()
$(function(){
//在整个HTML文档加载完之后立即执行..
})
等价于
window.onload = function(){}
2.3.JS对象和jQuery对象的互相转换
var oDiv = ...;//js
$(oDiv).css();
$("#div1")[0]
$("#div1").get(0)
3.选择器
3.1.基本选择器
元素名选择器
$("div")
class选择器
$(".c1")
ID选择器
$("#id值")
多元素选择器
$("div,span,p")
$("*")
3.2.层级选择器
$("div span")
$("div>span")
$("div+span")
$("div~span") ==
$("div").nextAll("span");
next()
nextAll();
prev()
prevAll()
siblings();
3.2.基本过滤选择器
$("div:first")
$("div:last")
$("div:eq(0)")
$("div:lt(3)")
$("div:gt(3)")
...
4.事件及方法
4.1.方法
html()
text()
attr()
css()
上面的方法除了可以获取值之外, 还可以设置值,
比如:
$("#div1").html() -- 获取当前元素的html内容
$("#div1").html("XXXX") -- 设置当前元素的html内容
show() display:block/inline
hide()
toggle()
4.2.事件
ready()
click()
change()
blur()
focus()
day12 Tomcat+HTTP -------------
1.Servlet容器、WEB容器、服务器
Servlet容器:能够运行Servlet程序的环境就是一个Servlet容器, 比如tomcat。
WEB容器: 能够运行WEB应用的环境就是一个WEB容器
2.TOMCAT下载、安装、配置
2.1.服务器下载
2.2.安装
tomcat7.0 解压版
在启动之前, 需配置JAVA_HOME环境变量
[tomcat]/bin/startup.bat 启动服务器
[tomcat]/bin/shutdown.bat 关闭服务器
2.3.配置
[tomcat]/conf/server.xml 70行 port=80
重启服务器
2.4.端口被占用导致服务器启动失败
方式一: shutdown.bat
方式二:
netstat -ano 80 3478
taskkill /f /pid 3478
3.tomcat服务器的目录结构
bin -- 批处理命令
conf -- 配置文件
lib -- jar包
logs -- 日志文件
temp -- 临时文件
webapps -- localhost虚拟主机默认管理的目录, 将WEB应用直接丢进这个目录下, 后期可以通过localhost主机访问
work -- 工作文件
4.WEB应用
4.1.WEB应用的目录结构
news
|
|-- 在非WEB-INF以外的目录下, html,css,js,jsp,图片..., 通过浏览器可以直接访问.
|
|-- WEB-INF 隐私目录, 放在这个目录下的资源, 不能通过浏览器直接访问(可以通过Servlet转发访问)
|
|-- classes .class文件
|-- lib jar包
|-- web.xml
4.2.如何部署WEB应用到虚拟主机中
news ---> localhost
直接将WEB应用的目录丢进虚拟主机所管理的目录即可!
4.3.如何配置缺省的WEB应用
WEB应用的目录改为ROOT即可!
在访问时就可以省略掉WEB应用名称:
http://localhost/day20/index.html -->
4.4.如何配置主页
在web.xml文件中配置
http://localhost/index.html --->
5.虚拟主机
5.1.如何配置一台虚拟主机
在[tomcat]/conf/server.xml Engine标签内添加:
<Host name="www.baidu.com" appBase="baidu"></Host>
配置后, 需要在DNS或hosts文件中配置主机名和IP地址的映射关系.
5.2.如何配置缺省的虚拟主机
<Engine name="CATALINA" defaultHost="localhost">
6.打war包
命令行
解压工具
xxx.zip --> xxx.war
HTTP协议
规定了浏览器和服务器通信的方式(格式)
基于请求响应模型
一次请求对应一次响应
请求只能由客户端发出, 服务器只能等待请求,处理请求, 做出响应
HTTP请求
请求行:
GET /news/1.html HTTP/1.1
若干请求头:
host: localhost
cookie: xxxx
Referer : xxx
....
(空行)
请求实体内容
HTTP响应
状态行:
HTTP/1.1 200 OK
若干响应头:
Set-Cookie : xxx
Content-Type: text/html;charset=utf-8
Content-Length: xx
Refresh : 3;url=XXXX
location : xxx
xxx : xxx
(空行)
响应实体内容
xxxx
day13 Servlet -------------
1.Servlet概述
1.1.什么是Servlet?
Servlet和JSP由SUN公司提供的动态WEB资源开发技术, 本质是一段Java程序, 这段程序需要放在Servlet容器中, 由容器调用才可以执行.
1.2.如何开发Servlet程序
(1)写一个类, 实现(间接实现)Servlet接口
(2)在WEB应用的web.xml文件中配置Servlet对外访问的虚拟路径
2.Servlet继承关系
Servlet
|
|-- GenericServlet, 实现Servlet大部分的方法,service没有实现
|
|-- HttpServlet, 实现了service方法, 根据不同的请求方式调用不同的doXxx方法
|
|--MyServlet
3.Servlet调用过程
略
4.Servlet开发细节
Servlet虚拟路径的配置
/ServletDemo1
/* /servlet/*
*.do *.action...
5.修改Servlet模版
day14 Request -------------
1.继承关系
ServletRequest
|
|-- HttpServletRequest
2.Request功能
1.获取客户端的基本信息、获取请求头信息、实现请求包含
2.获取请求参数
getParameter();
getParameterValues();
getParameterMap();
GET提交的参数乱码:
String username = request.getParameter("username");
username = new String( username.getBytes("iso8859-1"), "utf-8" );
POST提交的参数乱码:
request.setCharacterEncoding("utf-8")
3.实现请求转发
request.getRequestDispatcher("xxx").forward(request, response);
特点:
一次请求一次响应(request是同一个, 可以实现资源共享)
地址栏地址不会发生变化
只能在同一个WEB应用内部的资源之间进行跳转
4.作为域对象使用
setAttribute(String name,Object value);
getAttribute(String name);
removeAttribute(String name);
生命周期:
一次请求开始创建request对象, 一次请求结束销毁request对象.
doFilter(request, response, FilterChain);
作用范围: 一次请求链
主要功能: 在整个请求链中实现资源共享
day15 Response + ServletContext -------------
Response
1.继承关系
ServletResponse
|
|-- HttpServletResponse
2.Response常用方法
设置状态码的方法
setStatus();
设置响应头的方法
setHeader()
设置响应实体内容的方法
getOutputStream();
getWriter();
3.Response功能
3.1.向客户端发送数据
response.getOutputStream().writer("Hello".getByte());
response.getOutputStream().writer("哈喽".getByte("utf-8"));
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("Hello");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("哈喽");
3.2.实现重定向
response.sendRedirect("xxxx");
response.setStatus(302);
response.setHeader("location", "xxx");
特点:
两次请求两次响应(request不是同一个, 不能通过request共享数据)
地址栏地址会发生变化
可以实现在同一个或者不同的WEB应用或者不同的虚拟主机之间资源的跳转.
3.3.实现定时刷新
response.setHeader("Refresh", "3;url=xxxx");
特点:
两次请求两次响应(request不是同一个, 不能通过request共享数据)
地址栏地址会发生变化
可以实现在同一个或者不同的WEB应用或者不同的虚拟主机之间资源的跳转.
和重定向不同的是, 定时刷新可以在指定多少时间之后再进行跳转
ServletContext
代表整个WEB应用的对象
服务器启动后, WEB应用被加载之后, 服务器会立即创建代表当前WEB应用的ServletContext对象, 之后会一直驻留在服务器中唯一的代表当前WEB应用. 当服务器关闭或者WEB应用被移出容器, 随着WEB应用的销毁, ServletContext对象也跟着销毁
setAttribute()
getAttribute()
removeAttribute()
生命周期: 和WEB应用的命一样长
作用范围: 整个WEB应用
主要功能: 在整个WEB应用范围内实现资源的共享.
page
request
response
application
config
session
exception
out
pageContext
2.WEB阶段面试题汇总_2
3.面试题汇总
-
JSP和Servlet有哪些相同点和不同点?他们之间的联系是什么?
1.相同点: JSP和Servlet都可以用于接收客户端请求、处理请求,并做出响应。
2.不同点:
(1) Servlet更适合处理逻辑, 不适合作数据展示(即响应页面)
(2) JSP更适合展示数据, 不适合处理逻辑
(3) Servlet没有内置对象、JSP中有内置对象
(4) 在MVC设计模式中, Servlet属于控制器(Controller), JSP属于视图(View)
3.两者之间的联系:
JSP在一次被访问时, JSP引擎会对JSP进行编译, 编译后就变成了Servlet,本质上就是一个Servlet。
xxx.java
xxx.class
2.如果让你用socket实现一个简单的http服务器, 简述大体实现过程
自己完成!
3.转发和重定向的区别?
1.转发:可以在同一个WEB应用内部的资源之间进行跳转, 不可以是不同的WEB应用或者不同的虚拟主机.(转发时服务器会自动在传入的地址前面拼上WEB应用名称)
一次请求一次响应
地址栏地址不会发生变化
request对象是同一个, 可以在转发前后的两个资源之间共享数据
2.重定向:
可以在同一个WEB应用内部的资源之间进行跳转, 也可以是不同的WEB应用或者不同的虚拟主机.(转发时服务器会自动在传入的地址前面拼上WEB应用名称)
4.描述Cookie和Session的作用、区别 和 各自应用的范围, session的工作原理
1.Cookie和Session的作用:
Cookie和Session都是会话技术, 都可以用于保存会话过程中产生的数据, 比如作为购物车用于保存商品信息.
cookie可以实现记住用户名
Cookie实现30天自动登陆(过滤器)
2.Cookie和Session的区别:
Cookie是将会话中产生的数据保存到客户端, 是客户端技术
Session是将会话中产生的数据保存在服务器端, 是服务器端技术
cookie一般适合保存对安全性要求不高, 但是需要长时间保存的数据
session一般适合保存对时间要求不长, 但是要求具有一定安全性的数据
3.各自的应用范围:
Cookie: 客户端 实现购物车, 记住用户名, 实现30天自动登陆
session: 服务器 实现购物车, 保存用户的登陆状态
4.session的工作原理:
见上
5.js中加var和不加var的区别
1、声明变量时, 如果声明在方法外面, 不管加不加 var, 都是声明一个全局变量, 等价于为 window(全局对象)创建一个属性, 因此
var x = 100; // alert(x) == alert(window.x)
y = 200; // alert(y) == alert(window.y)
2、如果变量声明在方法内部, 加上 var 则声明一个局部变量, 不加 var 则是声明一个全局变量
<script>
var x = 100;
alert(x); //100
alert(window.x); //100
y = 200;
alert(y); //200
alert(window.y);//200
function fn(){
var m = 300;
alert(m); //300
alert(window.m) //undefined
n = 400;
alert(n); //400
alert(window.n);//400
}
fn();
</script>
6.简述http请求报文的结构(HTTP请求信息的格式)
请求行信息:
GET /test/index.jsp HTTP/1.1
若干请求头:
host : localhost
xxx : xxx
...
(一个空行)
请求实体内容
如果请求方式为GET提交, 请求实体中没有任何数据
如果请求方式为POST提交, 并且请求中携带了数据, 此时请求实体中才会有数据
7.Web开发中session的使用场景? 什么时候session失效?
1、session的使用场景:
实现购物车
保存用户登录状态
2、Session失效:
见上↑(超时30分不用、调用invalidate方法、服务器非正常关闭)
8.JavaWeb开发为什么要使用连接池
见上↑