玩命加载中 . . .

JSP详解


JSP:

指令

  • 作用:用于配置JSP页面,导入资源文件
  • 格式:
    <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 … %>
  • 分类:
    1. page : 配置JSP页面的
      • contentType:等同于response.setContentType()
        1. 设置响应体的mime类型以及字符集
        2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
      • language:java
      • import:导包
      • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
      • isErrorPage:标识当前也是是否是错误页面。
        • true:是,可以使用内置对象exception
        • false:否。默认值。不可以使用内置对象exception
    2. ** include : 页面包含的。导入页面的资源文件**
      • <%@include file=”top.jsp”%>
    3. taglib : 导入资源(标签库)
    4. 注释:
      1. html注释:(不建议使用,在响应体里还会被显示) :只能注释html代码片段
      2. jsp注释:推荐使用 <%– –%>:可以注释所有

内置对象

  • 在jsp页面中不需要创建,直接使用的对象
  • 一共有9个:
变量名                    真实类型                        作用

- pageContext        PageContext                     当前页面共享数据,还可获取其他八个内置对象
- request            HttpServletRequest             一次请求访问的多个资源(转发)
- session            HttpSession                    一次会话的多个请求间
- application        ServletContext                 所有用户间共享数据
- response            HttpServletResponse             响应对象
- page                Object                        当前页面(Servlet)的对象  this
- out                JspWriter                    输出对象,数据输出到页面上
- config            ServletConfig                Servlet的配置对象
- exception            Throwable                    异常对象

MVC:开发模式

  1. jsp演变历史

    1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
    2. 后来又jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表,造成难于维护,难于分工协作
    3. 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理性
  2. MVC:

  3. M:Model,模型。JavaBean

    • 完成具体的业务操作,如:查询数据库,封装对象
  4. V:View,视图。JSP

    • 展示数据
  5. C:Controller,控制器。Servlet

    • 获取用户的输入
    • 调用模型
    • 将数据交给视图进行展示
  6. 优缺点:

    1. 优点:
      1. 耦合性低,方便维护,可以利于分工协作
      2. 重用性高
    2. 缺点:
      1. 使得项目架构变得复杂,对开发人员要求高
image-20200504140128503

EL表达式

  1. 概念:Expression Language ==表达式==语言

  2. 作用:替换和简化jsp页面中java代码的编写

  3. 语法:${表达式}

  4. 注意:

    • jsp默认支持el表达式的。如果要忽略el表达式
      1. 设置jsp中page指令中:isELIgnored=”true” 忽略当前jsp页面中所有的el表达式
      2. ${表达式} :忽略当前这个el表达式
  5. 使用:

    1. 运算:

      • 运算符:
        1. 算数运算符: + - * /(div) %(mod)
        2. 比较运算符: > < >= <= == !=
        3. 逻辑运算符: &&(and) ||(or) !(not)
        4. 空运算符: empty
          • 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
          • ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
          • ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
    2. 获取值

      1. el表达式只能从域对象中获取值
        1. 语法:
          1. ${域名称.键名}:从指定域中获取指定键的值
            • 域名称:
              1. pageScope –> pageContext
              2. requestScope –> request
              3. sessionScope –> session
              4. applicationScope –> application(ServletContext)
            • 举例:在request域中存储了name=张三
            • 获取:${requestScope.name}
      2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
  6. 获取对象、List集合、Map集合的值

    1. 对象:${域名称.键名.属性名}
      • 本质上会去调用对象的getter方法
      • 属性名:get和set方法去掉get/set,剩余字符串首字母去掉大写,就是属性
          * 如:getName --> Name --> name
        
    2. List集合:${域名称.键名[索引]}
    3. Map集合:
      • ${域名称.键名.key名称}
        * ${域名称.键名["key名称"]}
        
  7. 隐式对象:

    • el表达式中有11个隐式对象

    • pageContext:

    • 获取jsp其他八个内置对象

      • ${pageContext.request.contextPath}:动态获取虚拟目录

JSTL:标签库

  1. 概念:JavaServer Pages Tag Library JSP标准==标签库==
  • 是由Apache组织提供的开源的免费的jsp标签 <标签>
  1. 作用:用于简化和替换jsp页面上的java代码

  2. 使用步骤:

    1. 导入jstl相关jar包
    2. 引入标签库:taglib指令: <%@ taglib %>
  3. 使用标签

  4. 常用的JSTL标签

  5. if:相当于java代码的if语句 1. 属性:

       *  test 必须属性,接受boolean表达式
           * 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
           * 一般情况下,test属性值会结合el表达式一起使用
    

    注意:

    • c:if标签没有else情况,想要else情况,则可以在定义一个c:if标签
``` 
<c:if test="${number%2 != 0 }"> 
//逻辑
</c:if>
```
  1. choose:相当于java代码的switch语句 1. 使用choose标签声明 相当于switch声明 2. 使用when标签做判断 相当于case
    • 属性:test 3. 使用otherwise标签做其他情况的声明 相当于default
``` 
<c:choose>
<c:when test="${number == 1}"> 星期一 </c:when>
<c:when test="${number == 2}"> 星期二 </c:when>
<c:otherwise> 输入有误 </c:otherwise>
</c:choose>
```
  1. foreach:相当于java代码的for语句

    1. 完成重复操作

      • 属性:

        begin:开始值

        end:结束值

        var:临时变量

        step:步长

        varStatus:循环状态对象

        • index:容器中元素的索引,从0开始

        • count:循环次数,从1开始

      <c:forEach begin="1" end="10" var="i" step="2" varStatus="s"(这个不常用)>
      ${s.index} ${s.count}
      </c:forEach>
      
    2. 遍历容器

      • 属性:

        items:容器对象

        var:容器中元素的临时变量,相当于for each中的元素名称

        varStatus:循环状态对象

        • index:容器中元素的索引,从0开始

        • count:循环次数,从1开始

      <%
      List list = new ArrayList();
      list.add("aaa");
      request.setAttribbute("list",list);
      %>
      <c:forEach items="${list}" var="str" varStatus="s">
      //索引 循环次数 遍历的元素
      ${s.index} ${s.count} ${str}
      </c:forEach>
      

三层架构

image-20200504175818407

  1. 界面层(表示层):用户看的得界面。用户可以通过界面上的组件和服务器进行交互
  2. 业务逻辑层:处理业务逻辑的。
  3. 数据访问层:操作数据存储文件。

案例1:用户信息列表展示

bug1:路径错误404
    使用跳转时:不加虚拟路径,并且注意资源名称的大小写
    使用超链接,按钮时:加虚拟路径,注意大小写
bug2:添加用户功能,不知道怎么在操作数据库类中获取表单数据
    将添加用户方法设置有参,传入一个servlet获取表单数据后并封装好的对象即可
bug3.1:修改用户信息功能,性别获取不到值
    性别的name值是sex,而数据库的是gender,修改相同即可

bug3.2:修改用户信息,获取值成功,但无法修改数据库值
    sql语句书写错误,虽然没有报错,但是应修改:当需要更改多个值时 应该用","连接,而不是"and"
    如: 正确:update user set gender=?,age=? where name=?;
        错误:update user set gender=? and age=? where name=?;
        
bug3.3:登录用户信息,获取值成功,但显示账号密码错误
    sql语句书写错误,看看where 后的参数名是否出错
    如:错:select * from user where name=?
        实际上是username=?
  1. 需求:用户信息的增删改查操作

  2. 设计:

    1. 技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtilS+tomcat
    2. 数据库设计:
      create database day17; – 创建数据库
      use day17; – 使用数据库
      create table user( – 创建表
       id int primary key auto_increment,
       name varchar(20) not null,
       gender varchar(5),
       age int,
       address varchar(32),
       qq    varchar(20),
       email varchar(50)
      
      );
  3. 开发:(程序员主负责第二步)

    1. 环境搭建

      1. 创建数据库环境
      2. 创建项目,导入需要的jar包
    2. 编码

  4. 测试

  5. 部署运维

image-20200504203115861

查询功能分析:
1.创建数据库,环境搭建(导入jar包,导入静态网页)
2.创建web.servlet、service、dao包
3.点击index.jsp进入UserListSerlet
4.UserListSerlet:调用service层中的findAll()方法,将返回值user对象存储进request域中,并转发到list.jsp页面
5.service层:需要用接口实现多态,实现类调用Dao层中的findAll()方法
6.0 创建domain包,创建user的javaBean类
6.dao层:需要用接口实现多态,实现类实现JDBC操作数据库功能实现查询,返回user对象(使用数据库连接池、JdbcTemplate技术)
7.list.jsp:将静态数据删掉,获取request域中的数据展示在页面上

案例2:综合案例分析

登录:
1.调整页面布局
2.将登录界面设置成jsp,并且展示验证码
3.0将数据库增加username,password,并且javaBean中也增加相应的成员变量和getset方法
3.登录跳转到loginServlet,获取数据,审核验证码,审核账号密码,储存信息,重定向到index.jsp,并显示名字,欢迎你
4.验证码或账号密码失败,都转发回login.jsp

添加功能:
注意:add()需要添加参数
add.jsp:提交到UserAddServlet
UserAddSerclet:设置编码格式,获取值,调用service层中的add(),转发到list.jsp页面
UserService接口:public void add(User newUser);
UserServiceImpl:public void add(User newUser){ dao.add(User newUser)}
UserDao接口:public void add(User newUser);
UserDaoImpl:public void add(User newUser){ jdbc操作数据库}
update user set gender=? and qq=? where name=?

修改:
1.list.jsp点击修改跳转到findUserServlet
2.fidUserServlet中获取id信息,调用findUser方法查询用户信息,存储到request中,跳转到update.jsp
3.update.jsp获取信息,回写信息(加上隐藏域id,用于通过id来修改对应的数据)
4.提交跳转到updateServlet,获取表单信息,调用数据库方法进行修改数据
5.uodateServlet跳转到list.jsp

删除选中:
    要求:
    1.复选框全选、全不选
    2.点击删除选中会提交对应id值
    3.删除选中加个判断,确定是否要删除
    4.不选时点删除选中时,不报空指针异常,先判断复选框的状态再进行删除操作
1.用javascript,获取总复选框id,设置单击事件,事件中获取其他复选框的name,遍历将其checked状态与总复选框相同
2.1将复选框设置value值,表格外嵌套表单,删除选中按钮设置单击事件,让其拥有提交表单功能
2.2提交到delSelectServlet,获取所有id值(数组),调用service中方法转入数组,跳转到listServlet
2.3service中遍历数组,分别调用del方法,传入id
3.用javascript,confirm()实现
4.前端:用javascript,获取所有复选框的name,遍历将其checked状态是否为checked,有一个就将flag变为true进行删除操作
  后端:2.3遍历数组前,判断数组是否不为空或长度大于0

分页查询:

image-20200506133933677

image-20200506134007778

bug1:实现当前页面被激活状态,按键消失
检查代码:<c:if test="${pb.currentPage == i}"> <li class="active">
    注意:不是${pb.currentPage}==${i}||${pb.currentPage}==i
重启服务器
bug2:实现下一页禁用状态,按钮分离
检查代码:不要多复制代码
bug3:NumberFormatException: null
获取的数据为空
if(currentPage==null||"".equals(currentPage)){
            currentPage="1";
}
if(rows==null||"".equals(rows)){
            rows="5";
}
分页查询分析:
    要求:
    1.点击页数提交当前页码,查询的条数
    2.实现分页查询5条数据
    3.获取总记录数,总页码,当前页码,每页的数据
    4.修改动态总记录数、总页码
    5.实现上下页功能
    6.实现当前页面为激活状态(前后端都要设置)
    7.实现当前页面为1或最后一页,上下一页功能被禁用(前后端都要设置)

1.点击页码,跳转到FindUserByPageServlet,并传参currentPage当前页面和rows每页显示条数
2.0 创建PageBean类,参数:总记录数、总页码、当前页码、查询条数、每页数据
2.FindUserByPageServlet:获取参数currentPage、rows,调用Service中的findUserByPage(传入参数),返回一个PageBean集合,将PageBean存入request中,转发到list.jsp进行展示,将list.jsp:表格遍历items:${pb.list}
3.Service中findUserByPage方法实现:
    创建PageBean对象,
    将当前页码、查询条数保存进对象中,
    调用dao中的findTotalCount()获取总记录数并保存进对象中,
    计算总页码:总记录数/查询条数,向上取整,保存进对象
    计算开始查询的页数:(当前页数-1)*查询条数
    调用dao中的findByPage(传入开始查询的页数、查询条数)方法获取每页数据,保存进对象
    返回对象
3.1dao中findTotalCount()、findByPage()方法实现
4.${pb.totalCount} ${pb.totalPage}
5.上一页:currentPage=${pb.currentPage-1}&rows=5
下一页:currentPage=${pb.currentPage+1}&rows=5
其他页数在遍历中改<c:forEach begin="1" end="${pb.totalPage}" var="i">
6.前端:<c:if test="${pb.currentPage == i}"> <li class="active"> 
  后端:if(currentPage<=0){
            currentPage=1;
        }
7.<c:if test="${pb.currentPage == 1}"> <li class="disabled">

复杂条件查询:

image-20200506181255362

bug0:getParameterMap获取不到值
1.form表单没有action
2.input表单没有name或name写错
bug1:拼接字符串将currentPage和row也拼了进去
在遍历key的时候,加个if判断将两个跳过
if("currentPage".equals(key)||"rows".equals(key)){
                continue;
}
bug2:拼接字符串需要注意的细节:
1.使用StringBuilder
2.拼接时要加空格 不然会拼接在一起,不符合sql语法
3.?代表的值用 集合params.toArray()来写:template.queryForObject(sql,Integer.class,params.toArray());
bug3:获得参数都正确,拼接字符串也正确,查的值不对
没有添加%,如:select * from user where 1 = 1 and name like %李%
所有在获取值时应该加上%
params.add("%"+value+"%");
复杂条件查询分析:
    要求:
    1.输入值 模糊查询出记录数,页数
    2.按照分页查询出对应的数据
    3.查询之后信息回写
    4.点击其他页信息传参
    
分析:
1.点击查询,提交表单,跳转到FindUserByPageServlet
2.FindUserByPageServlet:获取到表单的map集合,调用Service中的findUserByPage(传入map集合)
3.Service中findUserByPage方法实现:调用dao中的findTotalCount(传入map集合)
4.dao中findTotalCount()方法实现,
    Map.keySet获取键集合,再用遍历键集合获取value,
    判断value是否有值,如果有值证明用户输入了值,
    拼接字符串 select * from user where 1 = 1 ,sb.append(" and "+key+" like "?) ,获取值 params
    template.queryForObject(sql,Integer.class,params.toArray())
5.Service中findUserByPage方法实现:调用dao中的findByPage(传入map集合)
6.dao中的findByPage()方法实现,
    与4相同,额外值params中加上参数startPage、rows
    注意:加参数应该将 params的泛型改成Object,因为类型可以不同
7.信息回写:
    将condition获取到后,可以存入request中
    将表单的value值改为动态获取${condition.email[0]}
    注意:存的condition是map集合,获取的时候应该加下标[0]
8.点击其他页信息传参:将分页导航的链接都加上动态参数:
    &name=${condition.name[0]}&address=${condition.address[0]}……

文章作者: 小苏
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小苏 !
评论
  目录