新手项目:黑马旅行网(踩坑bug集合以及笔记)

在准备学习框架之前看黑马的视频有一个新手项目,可以JavaWeb巩固基础。有些地方需要注意顺便做个简短笔记。

github代码地址

踩的坑:

  • MYSQL数据库选项设置,一开始创建表默认字符集是latin1,需要改成utf-8,否则会乱码。
    解决办法:https://zhidao.baidu.com/question/2205726633389150788.html
    在这里插入图片描述
  • Maven的tomcat插件启动后登陆注册页面不知道为什么不能显示验证码,所以我直接用tomcat8启动的项目,正常。在这里插入图片描述
  • 使用tomcat8及以上需要修改resource下的druid.peoperties配置文件。driverClassName的值在mysql后面加上cj
    另外url的值后面要加上时区,否则会报错在这里插入图片描述
  • 模糊查询
    这是一条sql语句拼接的判断,如果rname有值则拼接进sql语句中查询。rname的值是用户在网页搜素输入的关键字参数。如果用户没有搜索关键字,rname的值应该是null,但是这里的null是字符串的"null",所以最后一个条件起关键作用,不然查询不出一条数据。
if (rname != null && rname.length()>0 && !"undefined".equalsIgnoreCase(rname) && !"null".equalsIgnoreCase(rname)){
            sql += " and rname like ?";
            params.add("%"+rname+"%");
        }
  • 注意有没有设置虚拟目录,否则页面跳转失败
location.href = "http://localhost/route_list.html?cid="+cid+"&rname="+rname;
  • 触发事件调用函数不加括号,因为加了括号的含义是立即执行而不是等待触发
// 失去焦点就检查一次
				$("#username").blur(checkUsername);
				$("#password").blur(checkPassword);
				$("#email").blur(checkEmail);

项目笔记:

  • 过滤器
    用来处理请求和响应的字符集,设置为utf8,并且响应的内容为html格式。加上通配符可以在访问所有页面前都经过此过滤器。
package cn.itcast.travel.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/*")
public class CharacterFilter implements Filter {
    @Override
    public void destroy() {
    }
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //父接口强转为子接口
        HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse)resp;
        //获取请求方法
        String method = request.getMethod();
        if (method.equalsIgnoreCase("post"))
            request.setCharacterEncoding("utf-8");
        //处理响应编码
        response.setContentType("text/html;charset=utf-8");
        chain.doFilter(request, response);
    }
    @Override
    public void init(FilterConfig config) throws ServletException {

    }

}
  • Servlet抽取
    鉴于将要编写多个servlet,为了简洁化代码,可以抽取一个BaseServlet作为父类,继承HttpServlet,重写service方法。后面编写的Servlet只需要继承BaseServlet并实现相关业务方法即可。前端页面只需要根据相关路径就可以获取数据

抽取类

package cn.itcast.travel.web.servlet;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class BaseServlet extends HttpServlet {
    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求路径
        String uri = req.getRequestURI();
        //获取方法名称
        String methodName = uri.substring(uri.lastIndexOf('/') + 1);
        //获取方法对象
        try {
            Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //执行方法
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

    /**
     * 将响应以json格式输出到页面
     * @param obj
     * @param response
     * @throws IOException
     */
    public void writeValue(Object obj,HttpServletResponse response) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        mapper.writeValue(response.getOutputStream(),obj);
    }

    /**
     * 直接返回一个对象的json字符串形式
     * @param obj
     * @return
     * @throws JsonProcessingException
     */
    public String writeValueAsStream(Object obj) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(obj);
    }
}

writeValue方法可以将数据以json格式直接输出到前台,所以抽取了这个方法。减少了重复度。
Servlet类
Servlet
前端页面请求
在这里插入图片描述

  • 分页查询与模糊查询
    从前台可以获取到当前页码和一页要显示的条数,其中还有搜索的关键字和分类,但有的参数可能为null,所以在dao实现类中的sql语句要进行拼接处理
@Override
    public List<Route> findByPage(int cid, int start, int pageSize, String rname) {
        String sql = "select * from tab_route where 1=1 ";
        //params储存参数
        ArrayList<Object> params = new ArrayList<>();
        if (cid != 0){
            sql += " and cid = ? ";
            params.add(cid);
        }
        if (rname != null && rname.length()>0 && !"undefined".equalsIgnoreCase(rname) && !"null".equalsIgnoreCase(rname)){
            sql += " and rname like ?";
            params.add("%"+rname+"%");
        }
        sql += " limit ? , ? ";
        params.add(start);
        params.add(pageSize);
        //最后要把params转换为数组
        List<Route> route = template.query(sql, new BeanPropertyRowMapper<Route>(Route.class), params.toArray());
        return route;
    }

关于分页查询有几个公式

		//设置总页数
        int totalPage = totalCount%pageSize==0 ? totalCount/pageSize : totalCount/pageSize + 1;

这段代码表示总页数,totalCount是总条数,可以根据dao来查询获得。

int start = (currentPage-1) * pageSize;

start是sql查询语句最后limit x , y 的x参数,表示从索引为x的记录开始查,一共查y条。

  • 使用正则表达式校验表单
//检查用户名方法
			function checkUsername() {
				var username = $("#username").val();
				var reg_username = /^\w{4,20}$/;           //正则表达式条件
				var flag = reg_username.test(username);
				if (flag){
					$("#username").css("border","");
				}else {
					$("#username").css("border","1px solid red");
				}
				return flag;
			}
  • $(document).ready用法

所有包括在$(document).ready()里面的元素或事件都将会在DOM完成加载之后立即加载,并且在页面内容加载之前,这点和onload不同

 $(document).ready(function() {
        showImg();
    });
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值