在准备学习框架之前看黑马的视频有一个新手项目,可以JavaWeb巩固基础。有些地方需要注意顺便做个简短笔记。
踩的坑:
- 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类
前端页面请求
- 分页查询与模糊查询
从前台可以获取到当前页码和一页要显示的条数,其中还有搜索的关键字和分类,但有的参数可能为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();
});