经过前几节的学习,我们已经找到之前碰到的问题的原因了。那么下面接着做项目学习。
建立时把web.xml也生成下,省的右面再添加。
会询问是否改为java ee环境?no就行,其实改过来也是可以的。这个不重要。
新建完毕后,看下当前的web.xml
欢迎界面不需要,删除即可。
我们开始写代码之前,还是重点关注下这个逻辑流程图,之前编程序都没注意这个,所以才发生错误不知道怎么回事。
web.xml很重要,这里配置了这个工程的入口。我们这个程序实际上是一个servlet程序,前端配合jsp网页展示。所以,入口就是规定servlet的名称及url。当部署在服务器后,我们的页面首先要访问servlet,之后拦截请求后,处理请求并获取参数,之后再传给前端的jsp网页去呈现。
在编写代码时,可以先写servlet,也可以先配置web.xml,也可以先写jsp文件,从逻辑上将,我们先去配置servlet的web.xml更好。
这里主要是配置servlet信息,如下:
eb1
index
com.xxx.xx
index
/index
主要是servlet及其mapping,然后各有两个项。
其中名称需要一致,类就指向之后要新建的类。然后url也可以随便指定,部署后就从这里进入。
这些类库都是配置好的,直接放入lib即可。放入后,所有类库需要buildpath,项目会自动加入reference libraries.
实体类根据数据库的表来创建。对于导航栏,有两个表需要用到:大类表和标签表。
实体类可放入vo包里。由于大类型包含小类型,所以小类型也得建类。
下面是具体实现:
tagl类:
package com.xx.vo;
/**
* 标签类
*
*/
public class Tag {
private int id;
private String name;
private String url;
public Tag() {
// TODO Auto-generated constructor stub
}
public Tag(int id, String name, String url) {
super();
this.id = id;
this.name = name;
this.url = url;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Tag [id=" + id + ", name=" + name + ", url=" + url + "]";
}
}
bigtype类
package com.xx.vo;
import java.util.ArrayList;
import java.util.List;
public class ProductBigType {
private int id;
private String name;
private String remarks;
private List smallTypeList = new ArrayList();
public ProductBigType() {
// TODO Auto-generated constructor stub
}
public ProductBigType(int id, String name, String remarks, List smallTypeList) {
super();
this.id = id;
this.name = name;
this.remarks = remarks;
this.smallTypeList = smallTypeList;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public List getSmallTypeList() {
return smallTypeList;
}
public void setSmallTypeList(List smallTypeList) {
this.smallTypeList = smallTypeList;
}
@Override
public String toString() {
return "ProductBigType [id=" + id + ", name=" + name + ", remarks=" + remarks + ", smallTypeList="
+ smallTypeList + "]";
}
}
smalltype类
package com.xx.vo;
public class ProductSmallType {
private int id;
private String name;
private String remarks;
private int bigTypeId;
public ProductSmallType() {
// TODO Auto-generated constructor stub
}
public ProductSmallType(int id, String name, String remarks, int bigTypeId) {
super();
this.id = id;
this.name = name;
this.remarks = remarks;
this.bigTypeId = bigTypeId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public int getBigTypeId() {
return bigTypeId;
}
public void setBigTypeId(int bigTypeId) {
this.bigTypeId = bigTypeId;
}
@Override
public String toString() {
return "ProductSmallType [id=" + id + ", name=" + name + ", remarks=" + remarks + ", bigTypeId=" + bigTypeId
+ "]";
}
}
其中,大类里用到了List和ArrayList,需要引导util包。
数据库交互主要是连接,关闭数据库,需要做成静态的,这样就一直存在。
DBUtil类
package com.xx.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 数据库交互类
*
*/
public class DBUtil {
// 主方法 用于测试
public static void main(String[] args) {
try {
DBUtil.getConn();
System.out.println("conn ok...");
} catch (Exception e) {
System.out.println("conn error...");
e.printStackTrace();
}
}
// 加载驱动
static {
try {
Class.forName("com.mysql.jdbc.Driver"); // 反射机制加载驱动
} catch (ClassNotFoundException e) {
System.out.println("error in forName...");
e.printStackTrace();
}
}
// 获取连接
public static Connection getConn() {
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ebuys?useUnicode=true&characterEncoding=utf8","root","1234");
} catch (SQLException e) {
System.out.println("error in DriverManager");
e.printStackTrace();
}
return conn;
}
// 完整关闭
public static void closeAll(Connection conn, PreparedStatement pstmt, ResultSet rs) {
closeResult(rs);
closeState(pstmt);
closeConn(conn);
}
// 关闭连接
private static void closeConn(Connection conn) {
if(null != conn) {
try {
conn.close();
} catch (SQLException e) {
System.out.println("error in close...");
e.printStackTrace();
}
}
}
// 关闭管道
private static void closeState(PreparedStatement pstmt) {
if(null != pstmt) {
try {
pstmt.close();
} catch (SQLException e) {
System.out.println("error in pstmt...");
e.printStackTrace();
}
}
}
// 关闭结果
private static void closeResult(ResultSet rs) {
if(null != rs) {
try {
rs.close();
} catch (SQLException e) {
System.out.println("error in rs...");
e.printStackTrace();
}
}
}
}
这里可以用main主方法来测试下是否能够连接,注意这些都是需要类库支持的,要是忘记引入,会发生错误。
现在来编写刚才web.xml规定的servlet,作用是将数据库内的信息传入页面。这里需要进行间接的数据库操作。
package com.xx.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.xx.service.ProductBigTypeService;
import com.xx.service.TagService;
import com.xx.service.impl.ProductBigTypeServiceImpl;
import com.xx.service.impl.TagServiceImpl;
import com.xx.vo.ProductBigType;
import com.xx.vo.Tag;
public class InitController extends HttpServlet {
private static final long serialVersionUID = 1L;
// 通过接口及其实例化来降低耦合度 让程序容易拓展
private ProductBigTypeService bigTypeService = new ProductBigTypeServiceImpl();
private TagService tagService = new TagServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 查询类别
List bigTypeList = bigTypeService.findAllBigType();
// 查询标签
List tagList = tagService.findAll();
// 查询结果放入作用域
req.setAttribute("bigTypeList", bigTypeList);
req.setAttribute("tagLiat", tagList);
//
req.getRequestDispatcher("/index.jsp").forward(req, resp);
}
}
这个类的思路是重写service来处理请求,并转发到index.jsp。处理过程用到了大类列表和标签列表,这就涉及到查询,这个查询是封装在服务的方法里的。
这里涉及的概念较多,服务被写为了接口,也就是可以理解为纯虚函数。具体在impl里实现方法。
大类列表是通过大类服务的获取大类方法实现的,标签列表是通过标签服务的获取标签方法实现的。两者思路是相同的,需要具体实现。
实现的过程中,大类还包括了小类,因此也需要相应的实现小类的服务和方法。
标签的较为简单,是单层的,先看标签的接口
package com.xx.service;
import java.util.List;
import com.xx.vo.Tag;
public interface TagService {
// 查询标签
List findAll();
}
其实现是
package com.xx.service.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.xx.service.TagService;
import com.xx.util.DBUtil;
import com.xx.vo.Tag;
public class TagServiceImpl implements TagService {
@Override
public List findAll() {
List list = new ArrayList();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DBUtil.getConn();
String sql = "SELECT * FROM T_TAG";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
Tag tag = new Tag();
tag.setId(rs.getInt("id"));
tag.setName(rs.getString("name"));
tag.setUrl(rs.getString("url"));
list.add(tag);
}
return list;
} catch (SQLException e) {
System.out.println("error in tagServiceImpl...");
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, rs);
}
return null;
}
}
再来看大类接口
package com.xx.service;
import java.util.List;
import com.xx.vo.ProductBigType;
public interface ProductBigTypeService {
// 查询大类信息
List findAllBigType();
}
其实现为
package com.xx.service.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.xx.service.ProductBigTypeService;
import com.xx.service.ProductSmallTypeService;
import com.xx.util.DBUtil;
import com.xx.vo.ProductBigType;
import com.xx.vo.ProductSmallType;
public class ProductBigTypeServiceImpl implements ProductBigTypeService {
private ProductSmallTypeService smallTypeService = new ProductSmallTypeServiceImpl();
@Override
public List findAllBigType() {
List list = new ArrayList();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DBUtil.getConn();
String sql = "SELECT * FROM T_BIGTYPE";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
ProductBigType pbt = new ProductBigType();
pbt.setId(rs.getInt("id"));
pbt.setName(rs.getString("name"));
pbt.setRemarks(rs.getString("remarks"));
List pst = smallTypeService.findByBigTypeId(rs.getInt("id"));
pbt.setSmallTypeList(pst);
list.add(pbt);
}
return list;
} catch (SQLException e) {
System.out.println("error in bigTypeServiceImpl...");
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, rs);
}
return null;
}
}
在组合列表时,用到了小类接口,这里需要传入大类的id
package com.xx.service;
import java.util.List;
import com.xx.vo.ProductSmallType;
public interface ProductSmallTypeService {
// 查询当前大类id对应的所有小类
List findByBigTypeId(int bigTypeId);
}
对应的实现是
package com.xx.service.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.xx.service.ProductSmallTypeService;
import com.xx.util.DBUtil;
import com.xx.vo.ProductSmallType;
public class ProductSmallTypeServiceImpl implements ProductSmallTypeService {
@Override
public List findByBigTypeId(int bigTypeId) {
List list = new ArrayList();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DBUtil.getConn();
String sql = "SELECT * FROM T_SMALLTYPE WHERE BIGTYPEID = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, bigTypeId);
rs = pstmt.executeQuery();
while(rs.next()) {
ProductSmallType pst = new ProductSmallType();
pst.setId(rs.getInt("id"));
pst.setName(rs.getString("name"));
pst.setRemarks(rs.getString("remarks"));
pst.setBigTypeId(bigTypeId);
list.add(pst);
}
return list;
} catch (SQLException e) {
System.out.println("error in ProductSmallTypeServiceImpl...");
e.printStackTrace();
} finally {
DBUtil.closeAll(conn, pstmt, rs);
}
return null;
}
}
这里用到个知识点,就是怎么用通配符写sql语句。
8 写index.jsp
接下来,就可以写jsp了。首先引入css和图片资源,之后新建index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
eb1
这里用到了jsp里的include指令。分别指向top和footer,先来看footer
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
Copyright © 2019 xx inc. All rights reserved.
再来看top,使用div来构建出导航栏。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Insert title here
这里先实现了主导航栏,用了c:foreach的写法。
下面看下实现效果,使用tomcat部署,打开网页:
也就是说前面写的都是正确的。今天的课程就到这里,接下来接着完善jsp页面和servlet类。