A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© software0210 初级黑马   /  2019-9-23 15:41  /  1199 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

        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);
               
               

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马