servlet入门
xml开发
1.创建类实现Servlet接口
2.实现service方法
3.在web.xml中进行配置
<servlet
<servlet-name
<servlet-class
<servlet-mapping
<servlet-name
<url-pattern
注解开发
1.创建类实现Servlet接口
2.实现service方法
3.在类上加@WebServlet("/访问路径")
servlet原理
自己描述
生命周期
init()
创建后执行 ,1次
service()
每次访问都会执行 ,多次
destory()
servlet销毁前执行 ,1次
创建时机
1.默认,第一次访问时创建
2.配置load-on-startup,值是正数
servlet线程安全问题
servlet是单例的,所有有线程安全问题,不要使用全局变量,使用局部成员变量(在service方法中定义!!)
######################################################################
servlet进行收尾
servlet的体系结构
Servlet
GenericServlet
HttpServlet(抽象类!!!)
开发用HttpServlet
doGet()
doPost()
请求方式有7种,常用的get.post!doget和dopost只有一个方法会被触发
servlet的访问路径的配置
/info
/user/*
*.do
/hehe.do
注意/*.do会报错
HTTP
一次访问对应的时一次请求+一次响应
默认端口 80(可以省略)
基于tcp
协议版本
1.1对链接进行复用
SPDY协议
请求
请求行
请求头
请求体
请求分为get和post
为了把数据提交到服务器
1.get 数据在请求行 login?username=zs&password=123 get请求没有请求体
2.post 数据在请求体 username=zs&password=123
get和post区别
1.数据显示
2.安全
3.长度
4.文件上传只能使用post
原理
,一次访问到服务器,服务器就会针对此次访问创建一个request和response对象,把2对象传给service方法
HttpServletRequest --> 接口!!! 多态的应用
request的api
获取请求行
request.getMethod() //获取请求方式
request.getContextPath()//获取虚拟路径
request.getRequestUri() //获取访问路径的URI
request.getRequestUrl() //获取访问路径的URL
URI和URL区别?
URL:完整的访问地址 http://localhost:8080/login
URI:访问路径 /login
获取请求头
request.getHeader("请求头")
常用头
USER-AGENT
REFERER 防盗链
获取请求参数(浏览器传递到服务器的数据!!!!)
request.getParameter("参数名") 通用!!!
request.getParameterValues("参数名") input type=checkbox
request.getParameterMap() 配合三方jar包使用
请求中文乱码
get
tomcat8开始,tomcat解决中文乱码
post
request.setCharacterEncoding("utf-8") 要在接收参数前使用 缓冲区的乱码
1.BaseServlet实现流程
实现过程中注意重点:
1.反射的调用流程
2.多态在BaseServlet的应用
3.this的具体含义
4.字符串的截取逻辑
a) 创建BaseServlet 继承 HttpServlet 重写service方法
b) 在service中使用反射完成对方法的分发
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//完成方法分发
//1.获取请求路径
String uri = req.getRequestURI(); // /travel/user/login
//2.获取方法名称
String methodName = uri.substring(uri.lastIndexOf('/') + 1);
//3.获取方法对象Method
method.invoke(this,req,resp);
}
c)通过创建BaseServlet的service方法,最终会反射执行目标Servlet的具体方法
@WebServlet("/user/*")
public class UserServlet extends BaseServlet {
public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//实现登录业务逻辑
}
}
2.分类实现思路(导航条)
完成过程中重点注意事项
1.重点时缓存的业务逻辑
2.缓存业务逻辑中数据格式的转换
3.前台业务逻辑中请求的发起时机
前台页面业务逻辑
a) 分类信息需要在页面显示时展示,所以需要在入口函数处触发逻辑
b) header.html页面ajax触发获取分类信息
$(function () {
//查询分类数据
$.get("category/findAll",{},function (data) {
var lis = '<li class="nav-active"><a href="index.html">首页</a></li>';
//遍历数组,拼接字符串(<li>)
for (var i = 0; i < data.length; i++) {
var li = '<li><a href="route_list.html?cid='+data[i].cid+'">'+data[i].cname+'</a></li>';
lis += li;
}
lis+= '<li><a href="favoriterank.html">收藏排行榜</a></li>';
//将lis字符串,设置到ul的html内容中
$("#category").html(lis);
});
});
后台业务逻辑
web层
获取分类集合转成json返回浏览器
List<Category> cs = service.findAll();
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
mapper.writeValue(response.getOutputStream(),cs);
service层(重点!!!)
缓存实现逻辑
1.先从缓存中获取数据
Set<Tuple> categorys = jedis.zrangeWithScores("category", 0, -1);
2.对缓存数据进行判断
if (categorys == null || categorys.size() == 0) {
//没有缓存,需要去dao层获取数据,然后存储
cs = categoryDao.findAll();
for (int i = 0; i < cs.size(); i++) {
jedis.zadd("category", cs.get(i).getCid(), cs.get(i).getCname());
}
}else{
//有缓存,将缓存中数据取出,进行格式转换
cs = new ArrayList<Category>();
for (Tuple tuple : categorys) {
Category category = new Category();
category.setCname(tuple.getElement());
category.setCid((int)tuple.getScore());
cs.add(category);
}
}
dao层
public List<Category> findAll() {
String sql = "select * from tab_category ";
return template.query(sql,new BeanPropertyRowMapper<Category>(Category.class));
}
3.分页实现思路
完成过程中重点注意事项
1.前台页面字符串的拼接(最重要!!!!,刚开始接触特别容易出错,开发会天天写)
2.分页的逻辑(前台/后台)
前台要注意数据传递的参数和请求的方式(get/post) 开发几乎都用post
后台要注意数据的封装和json的返回格式(content-type)
3.pageBean的封装思想和数据来源以及数据的作用
4.必须要多练,这样方便分析框架对应源码实现思路
分类分页显示必要条件
1,要知道数据来源(cid从什么地方获取,为什么要用cid)
2,如何跨html进行数据传递
前台页面业务逻辑
1.ajax异步发起分页请求
2.发请求时需要提供 cid/currentPage/pageSize 3个参数 ,注意 cid是根据需求决定 currentPage/pageSize是必要条件
3.在ajax成功回调中对分页数据进行显示(重点在字符串拼接)
$.get("route/pageQuery",{cid:cid},function (pb) {
$("#totalPage").html(pb.totalPage); //显示总页数
$("#totalCount").html(pb.totalCount); //显示总数据量
//拼接页码字符串
var lis = "";
var fristPage = '<li><a href="javascript:void(0)">首页</a></li>';
var beforePage = '<li class="threeword"><a href="javascript:void(0)">上一页</a></li>';
lis += fristPage;
lis += beforePage;
for (var i = 0; i <= pb.totalPage ; i++) {
var li;
//创建页码的li
li = '<li onclick="javascipt:load('+cid+','+i+')"><a href="javascript:void(0)">'+i+'</a></li>';
lis += li;
}
var lastPage = '<li class="threeword"><a href="javascript:;">末页</a></li>';
var nextPage = '<li class="threeword"><a href="javascript:;">下一页</a></li>';
lis += nextPage;
lis += lastPage;
$("#pageNum").html(lis);
});
}
后台页面业务逻辑
web层
1.接收cid/currentPage/pageSize参数
2.对参数进行处理 对数据做非空和默认值的处理
3.调用service的方法获取pageBean对象
4.把pageBean对象转成json返回浏览器
public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接受参数
String currentPageStr = request.getParameter("currentPage");
String pageSizeStr = request.getParameter("pageSize");
String cidStr = request.getParameter("cid");
int cid = 0;//类别id
//2.处理参数
if(cidStr != null && cidStr.length() > 0){
cid = Integer.parseInt(cidStr);
}
int currentPage = 0;//当前页码,如果不传递,则默认为第一页
if(currentPageStr != null && currentPageStr.length() > 0){
currentPage = Integer.parseInt(currentPageStr);
}else{
currentPage = 1;
}
int pageSize = 0;//每页显示条数,如果不传递,默认每页显示5条记录
if(pageSizeStr != null && pageSizeStr.length() > 0){
pageSize = Integer.parseInt(pageSizeStr);
}else{
pageSize = 5;
}
//3. 调用service查询PageBean对象
PageBean<Route> pb = routeService.pageQuery(cid, currentPage, pageSize);
//4. 将pageBean对象序列化为json,返回
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
mapper.writeValue(response.getOutputStream(),pb);
}
service层
封装PageBean对象
public PageBean<Route> pageQuery(int cid, int currentPage, int pageSize) {
//封装PageBean
PageBean<Route> pb = new PageBean<Route>();
//设置当前页码
pb.setCurrentPage(currentPage);
//设置每页显示条数
pb.setPageSize(pageSize);
//设置总记录数
int totalCount = routeDao.findTotalCount(cid);
pb.setTotalCount(totalCount);
//设置当前页显示的数据集合
int start = (currentPage - 1) * pageSize;//开始的记录数
List<Route> list = routeDao.findByPage(cid,start,pageSize);
pb.setList(list);
//设置总页数 = 总记录数/每页显示条数
int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize :(totalCount / pageSize) + 1 ;
pb.setTotalPage(totalPage);
return pb;
}
dao层
查询具体分页对应数据
String sql = "select * from tab_route where cid = ? limit ? , ?";
template.query(sql,new BeanPropertyRowMapper<Route>(Route.class),cid,start,pageSize);
查询总数据个数
String sql = "select count(*) from tab_route where cid = ?";
template.queryForObject(sql,Integer.class,cid);
|
|