书城项目历程记录1|cookie知识点之前

2023年12月9日

今天是跟着p222-225。
主要完成了将html文件转为jsp文件,完成服务器回显的基础。

1.完成jsp

这里就是先添加一个头文件代码,再改文件后缀。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

2.抽取jsp代码重复部分:head footer等到common目录下

书城项目历程记录1|cookie知识点之前_第1张图片
这里遗留了一个问题,好像页面布局出了一点问题。
然后在原jsp文件中使用静态包含

<%@ include file="/pages/common/head.jsp"%>

3.完成登录和注册失败的回显

在sevlet文件中setAttribute

req.setAttribute("msg", "用户名已存在");
req.setAttribute("username", username);
 req.setAttribute("email", email);

在jsp文件中获取

<%=request.getAttribute("msg")==null?"":request.getAttribute("msg")%>

2023年12月10日

今天是跟着p226-229。
主要完成代码结构的优化,利用到了反射和BeanUtils。

1.将LoginServlet和RegistServlet—》UserServlet

避免了代码冗余。这里涉及的操作就是整合方法,web.xml里面的配置,jsp里面的添加隐藏域和修改请求地址。
书城项目历程记录1|cookie知识点之前_第2张图片
书城项目历程记录1|cookie知识点之前_第3张图片

2.利用反射来选择对应的方法,而不是使用action+if,(这里要重点注意复习反射知识

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	String action = req.getParameter("action");
	try {
		// 获取 action 业务鉴别字符串,获取相应的业务 方法反射对象
		Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class,
		HttpServletResponse.class);
		// System.out.println(method);
		// 调用目标业务 方法
		method.invoke(this, req, resp);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

3.为了以后拓展功能,抽取出BaseServlet

主要操作就是修改继承关系。
书城项目历程记录1|cookie知识点之前_第4张图片

public abstract class BaseServlet extends HttpServlet {
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String action = req.getParameter("action");
		try {
			// 获取 action 业务鉴别字符串,获取相应的业务 方法反射对象
			Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
			// System.out.println(method);
			// 调用目标业务 方法
		method.invoke(this, req, resp);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

5.BeanUtils工具类的使用

为什么要使用?目的是避免req.getparameter的大量代码和创建对象的set的大量代码。
如何使用?
BeanUtils 工具类,它可以一次性的把所有请求的参数注入到 JavaBean 中。
BeanUtils 工具类,经常用于把 Map 中的值注入到 JavaBean 中,或者是对象属性值的拷贝操作。
BeanUtils 它不是 Jdk 的类。而是第三方的工具类。所以需要导包。
1、导入需要的 jar 包:
commons-beanutils-1.8.0.jar
commons-logging-1.1.1.jar
2、编写 WebUtils 工具类使用:
WebUtils 工具类:

public class WebUtils {
/**
* 把 Map 中的值注入到对应的 JavaBean 属性中。
* @param value
* @param bean
*/
	public static <T> T copyParamToBean( Map value , T bean ){
		try {
		System.out.println("注入之前:" + bean);
		/**
		* 把所有请求的参数都注入到 user 对象中
		*/
		BeanUtils.populate(bean, value);
		System.out.println("注入之后:" + bean);
		} catch (Exception e) {
		e.printStackTrace();
		}
	return bean;
	}
}

2023年12月11日

主要跟着p330-335

1.将jsp中的表单回显全部改成EL表达式

${requestScope.msg}$

2.MVC的概念

1、MVC 概念
MVC 全称:Model 模型、 View 视图、 Controller 控制器。
MVC 最早出现在 JavaEE 三层中的 Web 层,它可以有效的指导 Web 层的代码如何有效分离,单独工作。
View 视图:只负责数据和界面的显示,不接受任何与显示数据无关的代码,便于程序员和美工的分工合作——JSP/HTML。
Controller 控制器:只负责接收请求,调用业务层的代码处理请求,然后派发页面,是一个“调度者”的角色——Servlet转到某个页面。或者是重定向到某个页面。
Model 模型:将与业务逻辑相关的数据封装为具体的 JavaBean 类,其中不掺杂任何与数据处理相关的代码——JavaBean/domain/entity/pojo。
MVC 是一种思想
MVC 的理念是将软件代码拆分成为组件,单独开发,组合使用(目的还是为了降低耦合度)。
书城项目历程记录1|cookie知识点之前_第5张图片

3.图书模块开发(数据库,JavaBean,Dao)

整个模块的开发流程:
1、编写图书模块的数据库表
2、编写图书模块的 JavaBean
3、编写图书模块的 Dao 和测试 Dao
4、编写图书模块的 Service 和测试 Service
5、编写图书模块的 Web 层,和页面联调测试

3.1数据库表

创建t_book表,并插入测试数据。

3.2JavaBean

在pojo目录下创建Book类,对应表中属性,有参构造器,无参构造器,getter和setter以及tostring。这里注意imgPath的赋值。

3.3Dao与测试

先编写Dao接口,BookDao,增删改查。
再继承BaseDao,实现BookDao,编写BookDaoImpl(难点)。

public class BookDaoImpl extends BaseDao implements BookDao {
	@Override
	public int addBook(Book book) {
		String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`)
		values(?,?,?,?,?,?)";
		return update(sql,
		book.getName(),book.getAuthor(),book.getPrice(),book.getSales(),book.getStock(),book.getImgPath());
	}
	@Override
	public int deleteBookById(Integer id) {
		String sql = "delete from t_book where id = ?";
		return update(sql, id);
	}
	@Override
	public int updateBook(Book book) {
		String sql = "update t_book set `name`=?,`author`=?,`price`=?,`sales`=?,`stock`=?,`img_path`=?
		where id = ?";
		return
		update(sql,book.getName(),book.getAuthor(),book.getPrice(),book.getSales(),book.getStock(),book.ge
		tImgPath(),book.getId());
	}
	@Override
	public Book queryBookById(Integer id) {
		String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath
		from t_book where id = ?";
		return queryForOne(Book.class, sql,id);
	}
	@Override
	public List<Book> queryBooks() {
		String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath
		from t_book";
		return queryForList(Book.class, sql);
	}
}

Test技巧,在BookDao内容中,按下shift+ctrl+T,选择所有方法,选择Test目录,选择Junit4。进行测试,

2023年12月12日

今日观看p236-239。
主要完成service功能和web的一部分。
即:
4、编写图书模块的 Service 和测试 Service
5、编写图书模块的 Web 层,和页面联调测试

1.service部分

很简单,在service定义增删改查的接口,BookService,然后对应实现类(通过创建bookdao(BookDao实现类对象)操纵),再进行test。

2.Web层

首先要用专门处理book的Servlet(这里配置xml,注意地址/manager/bookService,原因是区分前后台)。BookServlet(继承BaseServlet)依旧是增删改查(通过创建book()service(BookService实现类对象)操纵)。
书城项目历程记录1|cookie知识点之前_第6张图片

3.针对展示所有图书,首先理清逻辑,(这里利用到页面–》servlet–》Dao获取数据–》最终页面)

书城项目历程记录1|cookie知识点之前_第7张图片
manager_menu,点击图书管理,(如何请求bookservlet?)
来自manager_menu.jsp

<a href="/manager/bookServlet?action=list">图书管理</a>

来自servlet

    protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1 通过BookService查询全部图书
        List<Book> books = bookService.queryBooks();
        //2 把全部图书保存到Request域中
        req.setAttribute("books", books);
        //3、请求转发到/pages/manager/book_manager.jsp页面
        req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
    }

如何列表展示,利用JSTL
来自book_manager.jsp

			<c:forEach items="${requestScope.books}" var="book">
				<tr>
					<td>${book.name}</td>
					<td>${book.price}</td>
					<td>${book.author}</td>
					<td>${book.sales}</td>
					<td>${book.stock}</td>
					<td><a href="/pages/manager/book_edit.jsp">修改</a></td>
					<td><a href="#">删除</a></td>
				</tr>
			</c:forEach>

4.添加图书功能,主要是是请求转发和重定向的区别!

当用户提交完请求,浏览器会记录下最后一次请求的全部信息。当用户按下功能键 F5,就会发起浏览器记录的最后一次请求。
请求转发:一次请求,到工程名。
重定向:两次请求,到端口号,因此要自己添加工程名。(防止F5刷新,重复提交业务)
书城项目历程记录1|cookie知识点之前_第8张图片

jsp文件中要添加,隐藏标签。

<form action="manager/bookServlet" method="get">
				<input type="hidden" name="action" value="add">

servlet

   protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //        1、获取请求的参数==封装成为Book对象
        Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book());
//        2、调用BookService.addBook()保存图书
        bookService.addBook(book);
//        3、跳到图书列表页面
//                /manager/bookServlet?action=list
//        req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req, resp);

        resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=list");

    }

2023年12月13日

今日完成240-242
把图书部分基本完成了。
主要解决,删除和修改。

1.在开始之前有几个错误需要记住

1.1 manager_mene.jsp 不要再静态包含head.jsp。导致了duplicate basePath
1.2 herf = “pages” ,不要在前面+/

2.删除,逻辑非常简单

书城项目历程记录1|cookie知识点之前_第9张图片

3.删除补充!因为删除了重要信息就不好了,所以需要弹窗!JQuery方面的知识完全忘记。

<script type="text/javascript">
		$(function () {
			// 给删除的a标签绑定单击事件,用于删除的确认提示操作
			$("a.deleteClass").click(function () {
				// 在事件的function函数中,有一个this对象。这个this对象,是当前正在响应事件的dom对象。
				/**
				 * confirm是确认提示框函数
				 * 参数是它的提示内容
				 * 它有两个按钮,一个确认,一个是取消。
				 * 返回true表示点击了,确认,返回false表示点击取消。
				 */
				return confirm("你确定要删除【" + $(this).parent().parent().find("td:first").text() + "】?");
				// return false// 阻止元素的默认行为===不提交请求
			});
		});
	</script>

对应绑定单击事件

<td><a class="deleteClass" href="manager/bookServlet?action=delete&id=${book.id}">删除</a></td>

4.修改图书:需要获取对应图书信息到book_edit.jsp(学习过的–》servlet–》bookedit)

书城项目历程记录1|cookie知识点之前_第10张图片

5.如何在book_edit页面知道,此时操作时add or update。老师给出了三种方法。

第一种是在请求的时候增加method参数,然后通过param.method获取。
第二种和第三种,分别是根据param.id是否有,和servlet重定向的requestScope.book。

2023年12月14日

今日主要跟着视频p243-245。初步完成了分页部分。主要是利用到了泛型。

1.将整个分页当做一个类。(下面这张图才是真正有价值的!)

书城项目历程记录1|cookie知识点之前_第11张图片

2.定义Page这个javabean。这里涉及到之后user列表等,所以设计成了泛型。

refacto-》rename,可以直接改为全大写等等命名

/**
 * Page是分页的模型对象
 * @param  是具体的模块的javabean类型,可以是user, book;
 */
public class Page<T> {
    public static final Integer PAGE_SIZE =4;
    private Integer pageNo;
    private Integer pageTotal;
    private Integer pageSize=PAGE_SIZE;
    private Integer pageTotalCount;
    private List<T> items;
}

3.自顶而下。从jsp请求servlet,servlet–》service–》dao一次完成逻辑。

4.dao部分,完成总记录数,和每个page,items的获取。

    @Override
    public Integer queryForPageTotalCount() {
        String sql = "select count(*) from t_book";
        Number count = (Number) queryForSingleValue(sql);
        return count.intValue();
    }

    @Override
    public List<Book> queryForPageItems(int begin, int pageSize) {
        String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath from t_book limit ?,?";

        return queryForList(Book.class, sql, begin, pageSize);
    }

4.service部分,通过调研dao,来完成page对象的创建和返回。

    @Override
    public Page<Book> page(Integer pageNo, Integer pageSize) {
        Page<Book> page = new Page<Book>();

        // 设置每页显示的数量
        page.setPageSize(pageSize);
        // 求总记录数
        Integer pageTotalCount = bookdao.queryForPageTotalCount();
        // 设置总记录数
        page.setPageTotalCount(pageTotalCount);
        // 求总页码
        Integer pageTotal = pageTotalCount / pageSize;
        if (pageTotalCount % pageSize > 0) {
            pageTotal+=1;
        }
        // 设置总页码
        page.setPageTotal(pageTotal);

        // 设置当前页码
        page.setPageNo(pageNo);

        // 求当前页数据的开始索引
        int begin = (page.getPageNo() - 1) * pageSize;
        // 求当前页数据
        List<Book> items = bookdao.queryForPageItems(begin,pageSize);
        // 设置当前页数据
        page.setItems(items);

        return page;
    }

5.servlet部分,通过调研service,获取page,将page set到req中,再请求转发。

   protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1获取pageNo和pageSize
        int pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 1);
        int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
        //2根据两个参数调用service
        Page<Book> page = bookService.page(pageNo, pageSize);
        //3保存到req
        req.setAttribute("page", page);
        //4请求转发
        req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);

    }

2023年12月18日

到现在从p246-253
主要实现分页(首页分页,图书管理分页,修改删除增加跳转分页(具体哪一页)的展示)。

1.实现了整个分页逻辑(显示5个可选页码)(完全按照老师的思路来。)

<%--分页条的开始--%>
<div id="page_nav">
    <%--大于首页,才显示--%>
    <c:if test="${requestScope.page.pageNo > 1}">
        <a href="${ requestScope.page.url }&pageNo=1">首页</a>
        <a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo-1}">上一页</a>
    </c:if>
    <%--页码输出的开始--%>
    <c:choose>
        <%--情况1:如果总页码小于等于5的情况,页码的范围是:1-总页码--%>
        <c:when test="${ requestScope.page.pageTotal <= 5 }">
            <c:set var="begin" value="1"/>
            <c:set var="end" value="${requestScope.page.pageTotal}"/>
        </c:when>
        <%--情况2:总页码大于5的情况--%>
        <c:when test="${requestScope.page.pageTotal > 5}">
            <c:choose>
                <%--小情况1:当前页码为前面3个:123的情况,页码范围是:1-5.--%>
                <c:when test="${requestScope.page.pageNo <= 3}">
                    <c:set var="begin" value="1"/>
                    <c:set var="end" value="5"/>
                </c:when>
                <%--小情况2:当前页码为最后3个,8910,页码范围是:总页码减4 - 总页码--%>
                <c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal-3}">
                    <c:set var="begin" value="${requestScope.page.pageTotal-4}"/>
                    <c:set var="end" value="${requestScope.page.pageTotal}"/>
                </c:when>
                <%--小情况34567,页码范围是:当前页码减2 - 当前页码加2--%>
                <c:otherwise>
                    <c:set var="begin" value="${requestScope.page.pageNo-2}"/>
                    <c:set var="end" value="${requestScope.page.pageNo+2}"/>
                </c:otherwise>
            </c:choose>
        </c:when>
    </c:choose>

    <c:forEach begin="${begin}" end="${end}" var="i">
        <c:if test="${i == requestScope.page.pageNo}">
            【${i}</c:if>
        <c:if test="${i != requestScope.page.pageNo}">
            <a href="${ requestScope.page.url }&pageNo=${i}">${i}</a>
        </c:if>
    </c:forEach>
    <%--页码输出的结束--%>


    <%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
    <c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
        <a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo+1}">下一页</a>
        <a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageTotal}">末页</a>
    </c:if>

    共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录
    到第<input value="${param.pageNo}" name="pn" id="pn_input"/><input id="searchPageBtn" type="button" value="确定">

    <script type="text/javascript">

        $(function () {
            // 跳到指定的页码
            $("#searchPageBtn").click(function () {

                var pageNo = $("#pn_input").val();

                <%--var pageTotal = ${requestScope.page.pageTotal};--%>
                <%--alert(pageTotal);--%>

                // javaScript语言中提供了一个location地址栏对象
                // 它有一个属性叫href.它可以获取浏览器地址栏中的地址
                // href属性可读,可写
                location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;

            });
        });

    </script>

</div>
<%--分页条的结束--%>

2.用户界面分页逻辑(index.jsp请求转发到clientbookservlet,servlet再转发到client目录下的index.jsp)

书城项目历程记录1|cookie知识点之前_第12张图片

2024年1月28日-1月29日

p253-256

1.设计根据价格区间对页码展示。

servlet–》service–》Dao
书城项目历程记录1|cookie知识点之前_第13张图片

2.实现过程,比较需要记住的就是一个快捷键,sql语言和如何保留翻页的查询状态

快捷键 alt+enter可以快速在相对应的文件中创建函数。
sql where price between min and max order by price;
保持查询状态,就是在ClientBookServlet文件中的pagebyPrice函数响应jsp时,设置page的url增加min和max;还有在jsp文件中,min和max设置默认值。

StringBuilder sb = new StringBuilder("client/bookServlet?action=pagebyPrice");
        if (req.getParameter("min")!=null){
            sb.append("&min=").append(req.getParameter("min"));
        }
        if (req.getParameter("max")!=null){
            sb.append("&max=").append(req.getParameter("max"));
        }
        page.setUrl(sb.toString());
<div class="book_cond">
            <form action="client/bookServlet" method="get">
                <input type="hidden" name="action" value="pagebyPrice">
                价格:<input id="min" type="text" name="min" value="${param.min}">-
                <input id="max" type="text" name="max" value="${param.max}"><input type="submit" value="查询" />
            </form>
        </div>

你可能感兴趣的:(书城项目,servlet,java,开发语言)