jsp

概念

  • Java server pages:Java服务器端页面

    可以理解为:一个特殊的页面,其中可以指定 定义html标签,又可以定义 java代码

    用于简化书写.

原理

  1. 服务器解析请去消息,找是否有 index.jsp 资源.
  2. 如果找到了,会将 index.jsp 转换为 .java文件
  3. 编译 .java文件,生成 .class字节码文件
  4. 由字节码文件提供访问
//启动 tomcat的时候可以查看,关闭的时候也可以
//在 idea中:Using CATALINA_BASE: 配置目录和源码中
//该目录的 work子目录是服务器解析的源码
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {}

jsp 的脚本

  • jsp定义 Java代码的方式:

    <% Java代码 %> :定义的 Java代码,在 service方法中,service方法中可以定义什么,该脚本就可以定义什么.

    <%! Java代码 %> :定义的Java代码,在 jsp转换后的Java类的成员位置.

    <%= Java代码 %>:定义的Java代码,会输出到页面上.输出语句中可以定义什么,该脚本就可以定义什么.
<%@ page import="java.sql.SQLOutput" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<%System.out.println("hello jsp");%>
<%! int a = 12; %>
<%= a %>
</body>
</html>
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.sql.SQLOutput; public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
//这里定义了成员变量
int a = 12;
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private static final java.util.Set<java.lang.String> _jspx_imports_packages; private static final java.util.Set<java.lang.String> _jspx_imports_classes; static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = new java.util.HashSet<>();
_jspx_imports_classes.add("java.sql.SQLOutput");
} private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
} public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
} public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
} public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
} public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
} public void _jspInit() {
} public void _jspDestroy() {
}
//主要看这个方法:我们可以使用 request, response
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException { if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
} final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null; try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out; out.write("\n");
out.write("\n");
out.write("<html>\n");
out.write("<head>\n");
out.write(" <title>首页</title>\n");
out.write("</head>\n");
out.write("<body>\n");
//输出语句
System.out.println("hello jsp");
out.write('\n');
out.write('\n');
//打印成员变量
out.print( a );
out.write("\n");
out.write("</body>\n");
out.write("</html>\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}

jsp的内置对象

  • 在 jsp页面中不需要获取和创建,可以直接使用的对象
  • 九大内置对象 (蓝色的是域对象)
    • request :HttpServletRequest :请求对象/获取请求资源 request域对象

      (同一个请求中使用)
    • response :HttpServletResponse :响应对象/响应响应的数据封装到响应对象
    • session :HttpSession :会话对象/实现多个用户之间数据共享

      (只能在同一个会话中使用私有的,会话:用户打开浏览器开始,到用户关闭浏览器这中间的过程)
    • pageContext :PageContext</java.lang.String> :jsp的上下文对象/当前页面实现数据共享,还可以获取其他八个内置对象

      (只能在当前 jsp页面使用)
    • application :ServletContext :ServletContext对象/全局域对象代表整个web应用

      (在同一个web应用中使用,对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效)
    • out :JspWriter (把他当作流对象字符输出流)可以间数据输出到页面上.和 response.getWriter()类似.

      response.getWriter()out.write() 的区别

      tomcat服务器真正给客户端做出响应之前,会先找 out缓冲区数据.response.getWriter()数据输出永远在 out.writer()之前

    • config :ServletConfig :ServletConfig对象/配置Servlet信息
    • exception :Throwable :异常对象/当页面需要声明 isErrorPage=true
    • page :Object :当前jsp的对象

指令

  • 作用:用于配置 jsp页面,导入资源文件
  • 格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
  • 分类:
    1. page:配置 jsp页面的

      • contentType:等同于 response.setContentType();

        设置响应体的 mime类型以及字符集

        设置当前 jsp页面的编码(只能是 高级的 ide才能生效,如果使用低级工具,则需要设置 pageEncoding属性设置当前页面的字符集)
      • import:导包
      • pageEncoding:设置当前页面的字符集
      • buffer:缓冲区的大小,默认 8kb
      • language:支持的语言
      • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
      • isErrorPage:表示当前页面,是否是错误页面

        true:是,可以使用内置对象 exception

        false:否,默认值,不可以使用内置对象 exception
    2. include:页面包含的。导入页面的资源文件

      <%@include file="页面名字.jsp" %>
    3. taglib:导入资源

      需要导入jar 包:jstl.jar,standard.jar

      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

注释

  1. html 注释: 只能注释 html 代码片段
  2. jsp 注释:<%-- --%> 可以注释所有《推荐使用》

mvc:开发模式

jsp演变历史

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

mvc

  • m:model,模型。JavaBean

    完成具体的业务操作,如:查询数据库,封装对象
  • v:view,视图。jsp

    展示数据
  • c:controller,控制器。servlet

    获取用户的输入

    调用模型

    将数据交给视图进行展示

优缺点

  1. 优点

    耦合性低方便维护,可利于分工协作
  2. 缺点

    使得项目构架变得复杂,对开发人员要求高

El表达式

  • 概念:expression language 表达式语言
  • 作用:替换和简化 jsp页面中 java代码的编写
  • 语法: ${}
  • 注意:

    jsp默认支持 el表达式。

    如果要忽略 el表达式

    1. 设置 jsp中 page指令中: isELIgnored="true"
    2. \${表达式} :忽略当前这个el表达式
  • 使用:
    1. 运算

      运算符:

      • 算数运算符:+ - * / %

        除法可以用 div表示,取余可以用 mod表示

      • 比较运算符:> < >= <= == !=
      • 逻辑运算符:&& || !

        and or not

      • 空运算符:empty

        功能:用于判断字符串,集合,数组,对象是否为 null并且长度是否为0

        ${empty list},判断字符串,集合,数组对象是否为 null,或者长度为0

        ${not empty str},表示判断字符串,集合,数组,对象是否不为 null并且 长度>0
    2. 获取值
      • le表达式只能从 域对象中获取值
      • 语法:
        1. ${域名称.键名}:从指定域中获取指定的值,如果该域中没有该键则显示空字符串

          • 域名称

            pageScope ===>pageContext

            requestScope ===>request

            sessionScope ===>session

            applicationScope ===>application(ServletContext)
          • 举例:

            在 request域中存储了 name=张三

            获取:${requestScope.name}
        2. ${键名}:依此从最小的域中查找是否有该键对应的值,直到找到为止。
    3. 获取,对象,list集合,map集合

      对象: ${域名称.键名.属性名}

      list集合: ${域名称.键名[索引]}

      map集合: ${域名称.键名.key名称} / ${域名称.键名["key名称"]}
      public class User {
      private String name;
      private Integer age;
      private Date birthday;
      /**
      * 格式化日期对象,返回字符串即可
      * @return 逻辑视图
      */
      public String formatDate() {
      if (birthday != null) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
      return sdf.format(birthday);
      }
      return null;
      } //省略 set get toString 无参 有参
      <%@ page import="com.cainiao.JavaBean.User" %>
      <%@ page import="java.util.*" %>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
      <title>Title</title>
      </head>
      <body>
      <%
      //对象
      User user = new User("张三", 22, new Date());
      request.setAttribute("user", user);
      //list集合
      List<User> list = new ArrayList<>();
      list.add(new User("AA", 18, new Date()));
      list.add(new User("bb", 20, new Date()));
      list.add(new User("cc", 22, new Date()));
      request.setAttribute("list", list);
      //map集合
      Map<String, Object> map = new HashMap();
      map.put("sname", "李四");
      map.put("gender", "男");
      map.put("user", user);
      request.setAttribute("map", map);
      %>
      <%--
      通过的是对象的属性来获取
      setXxx 或 getXxx方法,去掉 set或 get,在剩余部分,首字母变小写
      --%>
      ${requestScope.user}<br>
      ${requestScope.user.name}<br>
      ${user.age}<br>
      ${user.birthday}<br>
      年${user.birthday.year}
      月${user.birthday.month+1}
      日${user.birthday.date}<br>
      ${user.formatDate()}
      <hr>
      <%--list集合--%>
      ${list}<br>
      ${list[0].name}<br>
      ${list[1]}<br>
      ${list[2]}<br>
      ${list[5]}<br><%--下标越界,页面不显示--%>
      <hr>
      <%--map--%>
      ${map.sname}<%--第一种写法--%>
      ${map["gender"]}<%--另外一种写法--%>
      ${map.user.formatDate()}<%--对象--%>
      <hr>
      <%--empty运算符--%>
      ${empty list}<br><%--fase--%>
      ${empty list[4]}<br><%--true--%>
      ${empty str}<br><%--该str没有定义:true--%>
      </body>
      </html>
    4. 隐式对象
      • el表达式中有 11个隐式对象
      • pageContext:

        获取 jsp其他八个内置对象

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

JSTL 标签

  1. 概念: javaServer pages tag library :jsp标准标签库

    是由 apache组织提供的开源的免费的 jsp标签

  2. 作用:用于简化和替换 jsp页面上的Java代码

  3. 使用步骤

    • 导入 jstl相关的 jar包
    • 引入标签库:taglib指令: <%@ taglib %>
    • 使用标签
  4. jstl的标签库

    c标签(core标签库) <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

    fmt标签(国际化标签库) <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

    xml标签 <%@taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>

    sql标签 <%@taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>

    jstl函数库(el函数) <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

    使用频率最高的是核心库core标签库

  5. 常用的 jst标签

    • if :相当于Java代码的if语句

      属性:

      • text 必须属性,接收 boolean表达式

        如果表达式为 true,则显示 if标签体内容,如果为 false,则不显示标签体内容

        一般情况下,test属性值结合 el表达式一起使用

      注意:

      • c:if 标签没有 else情况,想要 else情况,则可以定义一个 c:if标签
      <%@ page import="java.util.ArrayList" %>
      <%@ page import="java.util.List" %>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <%--需要引入标签库--%>
      <html>
      <head>
      <title>Title</title>
      </head>
      <body>
      <%--
      c:if标签
      属性:
      text 必须属性,接收 boolean表达式
      如果表达式为 true,则显示 if标签体内容,如果为 false,则不显示标签体内容
      一般情况下,test属性值结合 el表达式一起使用
      注意:c:if 标签没有 else情况,想要 else情况,则可以定义一个 c:if标签 --%>
      <c:if test="true">
      <h1>我是真。。。</h1>
      </c:if><br>
      <%
      //判断 request 域中的一个 list集合是否我i空,如果不为 null则显示遍历集合
      List list = new ArrayList<>();
      list.add("aaa");
      request.setAttribute("list", list);
      %>
      <c:if test="${not empty list}">
      遍历集合。。。
      ${list}
      </c:if>
      </body>
      </html>
    • choose :相当于Java代码的switch语句

      1. 域中存储一数字
      2. 使用 choose标签取出数字 ====> 相当于 switch
      3. 使用 when标签做数字判断 ====> 相当于 case
      4. otherwise标签做其他情况的声明 ====> 相当于 default
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <html>
      <head>
      <title>Title</title>
      </head>
      <body>
      <%--
      完成数字编号对应星期几案例
      1. 域中存储一数字
      2. 使用 choose标签取出数字 相当于 switch
      3. 使用 when标签做数字判断 相当于 case
      4. otherwise标签做其他情况的声明 相当于 default
      --%>
      <%
      request.setAttribute("number", 12);
      %>
      <c:choose>
      <c:when test="${number==1}">星期一</c:when>
      <c:when test="${number==2}">星期二</c:when>
      <c:when test="${number==3}">星期三</c:when>
      <c:when test="${number==4}">星期四</c:when>
      <c:when test="${number==5}">星期五</c:when>
      <c:when test="${number==6}">星期六</c:when>
      <c:when test="${number==7}">星期日</c:when>
      <c:otherwise>数字输入有误</c:otherwise>
      </c:choose>
      </body>
      </html>
    • foreach :相当于Java代码的for语句

      <%@ page import="java.util.List" %>
      <%@ page import="java.util.ArrayList" %>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <html>
      <head>
      <title>Title</title>
      </head>
      <body>
      <%--
      foreach :相当于Java代码的for语句
      1. 完成重复的操作
      for (int i = 0; i <X; i++) {}
      属性:
      begin:开始值
      end:结束值
      var:变量
      step:步长
      varStatus:循环状态对象
      index:容器中元素的索引,从0开始
      count:循环次数
      2. 遍历容器
      for (Object o : ) {}
      属性:
      items:容器对象
      var:遍历容器中元素的临时变量
      varStatus:循环状态对象
      index:容器中元素的索引,从0开始
      count:循环次数
      --%>
      <c:forEach begin="1" end="10" var="i" step="1" varStatus="s">
      ${i} &nbsp;
      ${s.index} &nbsp;
      ${s.count}<br>
      </c:forEach>
      <hr>
      <%
      List list = new ArrayList();
      list.add("张三");
      list.add("李四");
      list.add("王五");
      request.setAttribute("list", list);
      %>
      <c:forEach items="${list}" var="str" varStatus="c">
      ${str}&nbsp; ${c.index}&nbsp; ${c.count}<br>
      </c:forEach>
      </body>
      </html>
    • 格式化日期标签

      <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
      <fmt:formatDate value="${user.birthday}" pattern="yyyy-MM-dd HH:mm:ss"/>

练习

  • 需求:在 request域中有一个存有 User对象的 list集合.需要使用 jstl + el将 list集合数据展示到 jsp页面的表格 table中
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.cainiao.JavaBean.User" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
List list = new ArrayList();
list.add(new User("zhangSan", 22, new Date()));
list.add(new User("liSi", 23, new Date()));
list.add(new User("wangWu", 25, new Date()));
request.setAttribute("list", list);
%>
<table border="1" align="center">
<tr>
<th>#</th>
<th>姓名</th>
<th>年龄</th>
<th>生日</th>
</tr>
<c:forEach items="${list}" var="u" varStatus="s">
<%--如果 index是偶数就显示粉色--%>
<c:if test="${s.index%2==0}">
<tr bgcolor="#ffc0cb">
<td>${s.index}</td>
<td>${u.name}</td>
<td>${u.age}</td>
<td>${u.formatDate()}</td>
</tr>
</c:if>
<%--如果 index不是偶数显示天蓝色--%>
<c:if test="${s.index%2!=0}">
<tr bgcolor="#afeeee">
<td>${s.index}</td>
<td>${u.name}</td>
<td>${u.age}</td>
<td>${u.formatDate()}</td>
</tr>
</c:if> </c:forEach>
</table>
</body>
</html>

三层架构:软件设计架构

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

案例:用户信息列表展示

  1. 用户信息的增删改查操作
  2. 设计
    • 技术选型:Servlet+jsp+myslq+jdbcTempleat+Duird+BeanUtils+tomcat
    • 数据库设计:
      use test;
      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)
      );
    • 开发:
      1. 环境搭建

        创建数据库环境

        创建项目,导入需要的jar包
      2. 编码过程

        页面下载:https://wwr.lanzoui.com/il40ityvhta

        代码下载:https://wwr.lanzoui.com/iSoocu0r7ba
    • 测试
    • 部署运维
public class JDBCUtils {
private static DataSource ds;
static {
try {
Properties pro = new Properties();
//InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
} public static DataSource getDataSource() {
return ds;
} public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
public class User {
private Integer id;
private String name;
private String gender;
private Integer age;
private String address;
private String qq;
private String email;
private String username;
private String password;
public interface UserService {

    /**
* 查询所有用户信息
*
* @return
*/
public List<User> findAll(); /**
* 登录方法
*
* @param user
* @return
*/
User login(User user); /**
* 保存User
*
* @param user
*/
void addUser(User user); /**
* 根据id删除User
*
* @param id
*/
void deleteUser(String id); /**
* 根据id查询
*
* @param id
* @return
*/
User findUserById(String id); /**
* 修改用户信息
*
* @param user
*/
void updateUser(User user); /**
* 批量删除用户
*
* @param ids
*/
void delSelectedUser(String[] ids); /**
* 分页条件查询
*
* @param currentPage
* @param rows
* @param condition
* @return
*/
PageBean<User> findUserByPage(String currentPage, String rows, Map<String, String[]> condition);
}
import java.util.List;
import java.util.Map; public class UserServiceImpl implements UserService {
private UserDao dao = new UserDaoImpl(); @Override
public List<User> findAll() {
//调用Dao完成查询
return dao.findAll();
} @Override
public User login(User user) {
return dao.findUserByUserNameAndPassword(user.getUsername(), user.getPassword());
} @Override
public void addUser(User user) {
dao.add(user);
} @Override
public void deleteUser(String id) {
dao.delete(Integer.parseInt(id));
} @Override
public User findUserById(String id) {
return dao.findById(Integer.parseInt(id)); } @Override
public void updateUser(User user) {
dao.update(user);
} @Override
public void delSelectedUser(String[] ids) {
//要避免空指针异常
if (ids != null && ids.length > 0) {
//1.遍历数组
for (String id : ids) {
//2.调用dao删除
dao.delete(Integer.parseInt(id));
}
} } @Override
public PageBean<User> findUserByPage(String _currentPage, String _rows, Map<String, String[]> condition) {
int currentPage = Integer.parseInt(_currentPage);
int rows = Integer.parseInt(_rows);
if (currentPage <= 0) {
currentPage = 1;
}
//1.创建空的PageBean对象
PageBean<User> pb = new PageBean<User>();
//2.设置参数
pb.setCurrentPage(currentPage);
pb.setRows(rows); //3.调用dao查询总记录数
int totalCount = dao.findTotalCount(condition); pb.setTotalCount(totalCount);
//4.调用dao查询List集合
//计算开始的记录索引
int start = (currentPage - 1) * rows;
List<User> list = dao.findByPage(start, rows, condition);
pb.setList(list);
//5.计算总页码
int totalPage = (totalCount % rows) == 0 ? totalCount / rows : (totalCount / rows) + 1;
pb.setTotalPage(totalPage); return pb; }
}
public interface UserDao {

    List<User> findAll();

    User findUserByUserNameAndPassword(String username, String password);

    void add(User user);

    void delete(int id);

    User findById(int id);

    void update(User user);

    //查询总记录数
int findTotalCount(Map<String, String[]> condition);
//分页查询 list
List<User> findByPage(int start, int rows, Map<String, String[]> condition);
}
public class UserDaoImpl implements UserDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); @Override
public List<User> findAll() { String sql = "select * from user";
List<User> list = template.query(sql, new BeanPropertyRowMapper<User>(User.class)); return list;
} @Override
public User findUserByUserNameAndPassword(String username, String password) {
try {
String sql = "select * from user where username=? and password = ?";
User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password);
return user;
} catch (DataAccessException e) {
e.printStackTrace();
}
return null;
} @Override
public void add(User user) {
//1. 定义 sql
String sql = "insert into user values(null, ?,?,?,?,?,? ,null,null)";
template.update(sql, user.getName(), user.getGender(), user.getAge(), user.getAddress()
, user.getQq(), user.getEmail()); } @Override
public void delete(int id) {
String sql = "delete from user where id =?";
template.update(sql, id);
} @Override
public User findById(int id) {
String sql = "select * from user where id =?";
return template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
} @Override
public void update(User user) {
String sql = "update user set name=? ,gender=?," +
"age=?,address=?,qq=?,email=? where id =?";
template.update(sql, user.getName(), user.getGender(), user.getAge()
, user.getAddress(), user.getQq(), user.getEmail(), user.getId());
} @Override
public int findTotalCount(Map<String, String[]> condition) {
//1. 定义模板初始化 sql
String sql = "select count(*) from user where 1 = 1 ";//注意留空格
StringBuilder sb = new StringBuilder(sql);
//2. 遍历 map
Set<String> keySet = condition.keySet();
//定义参数的集合
List<Object> params = new ArrayList<>();
for (String k : keySet) {
//排除分页条件参数
if ("currentPage".equals(k) || "rows".equals(k)) {
continue;
} //获取 value
String value = condition.get(k)[0];
//判断 value 是否有值
if (value != null && !"".equals(value)) {
//有值
sb.append(" and " + k + " like ? ");
params.add("%" + value + "%");//加条件的值
}
}
return template.queryForObject(sb.toString(), Integer.class, params.toArray());
} @Override
public List<User> findByPage(int start, int rows, Map<String, String[]> condition) {
String sql = "select * from user where 1 = 1 ";
StringBuilder sb = new StringBuilder(sql);
//2. 遍历 map
Set<String> keySet = condition.keySet();
//定义参数的集合
List<Object> params = new ArrayList<>();
for (String k : keySet) {
//排除分页条件参数
if ("currentPage".equals(k) || "rows".equals(k)) {
continue;
} //获取 value
String value = condition.get(k)[0];
//判断 value 是否有值
if (value != null && !"".equals(value)) {
//有值
sb.append(" and " + k + " like ? ");
params.add("%" + value + "%");//加条件的值
}
}
//添加分查询
sb.append(" limit ? , ? ");
//添加分页查询参数
params.add(start);
params.add(rows);
return template.query(sb.toString(), new BeanPropertyRowMapper<User>(User.class), params.toArray());
}
}

@WebServlet("/userListServlet")
public class UserListServlet extends HttpServlet { @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取 UserService 实现类
UserDao service = new UserDaoImpl();
List<User> users = service.findAll();
//2. 向请求域中存储 集合 users信息
request.setAttribute("users", users);
//3. 转发到 list页面,展示
request.getRequestDispatcher("/list.jsp").forward(request, response);
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

@WebServlet("/addUserServlet")
public class AddUserServlet extends HttpServlet { @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 设置编码
request.setCharacterEncoding("utf-8");
//2. 获取参数
Map<String, String[]> map = request.getParameterMap();
//3. 封装对象
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
//4. 调用 service保存
UserService service = new UserServiceImpl();
service.addUser(user);
//5. 跳转到 userListServlet 因为添加了分页所以跳转到 findUserByPageServlet
response.sendRedirect(request.getContextPath() + "/findUserByPageServlet"); } @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

@WebServlet("/delSelectedServlet")
public class DelSelectedServlet extends HttpServlet { @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取所有id
String[] values = request.getParameterValues("uid");
//2. 调用 service删除
UserService service = new UserServiceImpl();
service.delSelectedUser(values);
//3. 重定向 跳转到查询所有的 servlet
response.sendRedirect(request.getContextPath() + "/userListServlet"); } @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

@WebServlet("/findUserServlet")
public class FindUserServlet extends HttpServlet { @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取id
String id = request.getParameter("id");
//2. 调用 service查询
UserService service = new UserServiceImpl();
User user = service.findUserById(id);
//3. 将 user存储 request
request.setAttribute("user", user);
//4. 转发 update.jsp
request.getRequestDispatcher("/update.jsp").forward(request, response);
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
} @WebServlet("/updateUserServlet")
public class UpdateUserServlet extends HttpServlet { @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 设置编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
//2. 获取 map
Map<String, String[]> map = request.getParameterMap();
//3. 封装好对象
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
//4. 调用 service修改
UserService service = new UserServiceImpl();
service.updateUser(user);
//5. 重定向到查询所有 userListService
response.sendRedirect(request.getContextPath() + "/userListServlet");
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

@WebServlet("/delSelectedServlet")
public class DelSelectedServlet extends HttpServlet { @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取所有id
String[] values = request.getParameterValues("uid");
//2. 调用 service删除
UserService service = new UserServiceImpl();
service.delSelectedUser(values);
//3. 重定向 跳转到查询所有的 servlet
response.sendRedirect(request.getContextPath() + "/userListServlet"); } @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

/**
* 分页对象
* 好处:
* 1. 减轻服务器内存的开销
* 2. 提升用户体验
*
* @param <T>
*/
public class PageBean<T> {
//总记录数
private int totalCount;
//总页码=总记录数 % 每页显示条数 == 0 ? 总记录数/每页显示条数 : 总记录数/每页显示条数+1;
private int totalPage;
private List<T> list; //每页的数据 list集合
private int currentPage; //当前页码
private int rows;// 每页显示的条数
}

@WebServlet("/findUserByPageServlet")
public class FindUserByPageServlet extends HttpServlet { @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//1. 获取参数
String currentPage = request.getParameter("currentPage");//但其那页码
String rows = request.getParameter("rows");//每页显示条数
//如果当前页面为空则显示1,如果 rows为空显示5
if (currentPage == null || "".equals(currentPage)) {
currentPage = "1";
}
if (rows == null || "".equals(rows)) {
rows = "5";
}
//获取条件查询参数
Map<String, String[]> condition = request.getParameterMap();
//2. 调用 service查询
UserService service = new UserServiceImpl();
PageBean<User> page = service.findUserByPage(currentPage, rows, condition);
//3. 将 pageBean存入 request
request.setAttribute("page", page);
request.setAttribute("condition", condition);
//4. 转发到 list.jsp
request.getRequestDispatcher("/list.jsp").forward(request, response);
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>用户信息管理系统</title> <!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<style type="text/css">
td, th {
text-align: center;
}
</style> <script>
function deleteUser(id) {
//用户安全提示
if (confirm("您确定要删除吗?")) {
//访问路径
location.href = "${pageContext.request.contextPath}/delUserServlet?id=" + id;
}
} window.onload = function () {
//给删除选中按钮添加单击事件
document.getElementById("delSelected").onclick = function () {
if (confirm("您确定要删除选中条目吗?")) { var flag = false;
//判断是否有选中条目
var cbs = document.getElementsByName("uid");
for (var i = 0; i < cbs.length; i++) {
if (cbs[i].checked) {
//有一个条目选中了
flag = true;
break;
}
} if (flag) {//有条目被选中
//表单提交
document.getElementById("form").submit();
} } } //全选,全不选
//1.获取第一个cb
document.getElementById("firstCb").onclick = function () {
//2.获取下边列表中所有的cb
var cbs = document.getElementsByName("uid");
//3.遍历
for (var i = 0; i < cbs.length; i++) {
//4.设置这些cbs[i]的checked状态 = firstCb.checked
cbs[i].checked = this.checked;
}
}
} </script>
</head>
<body>
<div class="container">
<h3 style="text-align: center">用户信息列表</h3> <div style="float: left;"> <form class="form-inline" action="${pageContext.request.contextPath}/findUserByPageServlet" method="post">
<div class="form-group">
<label for="exampleInputName2">姓名</label>
<input type="text" name="name" value="${condition.name[0]}" class="form-control" id="exampleInputName2">
</div>
<div class="form-group">
<label for="exampleInputName3">籍贯</label>
<input type="text" name="address" value="${condition.address[0]}" class="form-control"
id="exampleInputName3">
</div> <div class="form-group">
<label for="exampleInputEmail2">邮箱</label>
<input type="text" name="email" value="${condition.email[0]}" class="form-control"
id="exampleInputEmail2">
</div>
<button type="submit" class="btn btn-default">查询</button>
</form> </div> <div style="float: right;margin: 5px;"> <a class="btn btn-primary" href="${pageContext.request.contextPath}/add.jsp">添加联系人</a>
<%--给删除选中绑定单击事件--%>
<a class="btn btn-primary" href="javascript:void(0);" id="delSelected">删除选中</a> </div>
<form id="form" action="${pageContext.request.contextPath}/delSelectedServlet" method="post">
<table border="1" class="table table-bordered table-hover">
<tr class="success">
<th><input type="checkbox" id="firstCb"></th>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>QQ</th>
<th>邮箱</th>
<th>操作</th>
</tr> <c:forEach items="${page.list}" var="user" varStatus="s">
<tr>
<td><input type="checkbox" name="uid" value="${user.id}"></td>
<td>${s.count}</td>
<td>${user.name}</td>
<td>${user.gender}</td>
<td>${user.age}</td>
<td>${user.address}</td>
<td>${user.qq}</td>
<td>${user.email}</td>
<td><a class="btn btn-default btn-sm"
href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a>&nbsp;
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a></td>
</tr> </c:forEach> </table>
</form>
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
<c:if test="${page.currentPage == 1}">
<li class="disabled"> </c:if> <c:if test="${page.currentPage != 1}">
<li>
</c:if> <a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${page.currentPage - 1}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}"
aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li> <c:forEach begin="1" end="${page.totalPage}" var="i"> <c:if test="${page.currentPage == i}">
<li class="active"><a
href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">
${i}</a>
</li>
</c:if> <c:if test="${page.currentPage != i}">
<li>
<a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">
${i}</a>
</li>
</c:if> </c:forEach> <c:if test="${page.currentPage ==page.totalPage }">
<li class="disabled"> </c:if> <c:if test="${page.currentPage != page.totalPage }">
<li>
</c:if>
<a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${page.currentPage + 1}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}"
aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
<span style="font-size: 25px;margin-left: 5px;">
共${page.totalCount}条记录,共${page.totalPage}页
</span>
</ul>
</nav>
</div>
</div>
</body>
</html>

jsp&mvc开发模式&jstl标签&三层架构的更多相关文章

  1. MVC开发模式与javaEE三层架构

    1.MVC开发模式 1. M:Model,模型.JavaBean        * 完成具体的业务操作,如:查询数据库,封装对象2. V:View,视图.JSP        * 展示数据3. C:C ...

  2. 【转】asp.net mvc(模式)和三层架构(BLL、DAL、Model)的联系与区别

    原文地址:http://blog.csdn.net/luoyeyu1989/article/details/8275866 首先,MVC和三层架构,是不一样的. 三层架构中,DAL(数据访问层).BL ...

  3. asp.net mvc(模式)和三层架构(BLL、DAL、Model)的联系与区别 转载自:http://blog.csdn.net/luoyeyu1989/article/details/8275866

    首先,MVC和三层架构,是不一样的. 三层架构中,DAL(数据访问层).BLL(业务逻辑层).WEB层各司其职,意在职责分离. MVC是 Model-View-Controller,严格说这三个加起来 ...

  4. 13 JSP、MVC开发模式、EL表达式和JSPL标签+软件设计架构---学习笔记

    1.JSP (1)JSP概念:Java Server Pages 即java服务器端页面可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码用于简化书写!!! (2)原理 ...

  5. MVC:开发模式&&三层架构:软件设计架构

    MVC:开发模式 jsp演变历史 早期只有servlet,只能使用response输出标签数据,非常麻烦 后来又jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码 ...

  6. MVC开发模式之Servlet+jsp+javaBean

    Servlet+jsp+JavaBean组合开发是一种MVC开发模式,控制器Controller采用Servlet.模型Model采用JavaBean.视图View采用JSP. 1.Web开发的请求- ...

  7. jsp学习笔记:mvc开发模式

    jsp学习笔记:mvc开发模式2017-10-12 22:17:33 model(javabe)与view层交互 view(视图层,html.jsp) controller(控制层,处理用户提交的信息 ...

  8. javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册

    一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...

  9. 咸鱼入门到放弃11--Servlet+JSP+JavaBean开发模式

    本篇搬运了大佬blog:https://www.cnblogs.com/xdp-gacl/p/3902537.html 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servle ...

随机推荐

  1. Docker部署Zookeeper部署实践(1)

    Zookeeper可提供的服务主要有:配置服务.名字服务.分布式同步.组服务等 1. 抓取Zookeeper镜像 命令:docker pull zookeeper 2. 将Zookeeper镜像保存为 ...

  2. 跟我一起写 Makefile(十一)

    make 的运行 ------ 一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的.但也有时你也许只想让make重编译某些文件,而不 ...

  3. 慕慕生鲜上线&&腾讯云服务器配置准备

    1.购买服务器并配置环境 1.1 购买 618购买了腾讯云服务器三年最低配置(1核2G 1Mbps 50G云盘),一时激动忘记了购买前领优惠券,痛失25元. 1.2 环境配置 系统是 CentOS L ...

  4. 剖析虚幻渲染体系(10)- RHI

    目录 10.1 本篇概述 10.2 RHI基础 10.2.1 FRenderResource 10.2.2 FRHIResource 10.2.3 FRHICommand 10.2.4 FRHICom ...

  5. Beescms V4.0_R_20160525代码审计笔记

    写在前面 什么是报错注入?正常用户访问服务器发送id信息返回正确的id数据.报错注入是想办法构造语句,让错误信息中可以显示数据库的内容:如果能让错误信息中返回数据库中的内容,即实现SQL注入. 复现过 ...

  6. 【Tools】SSHUsage

    SSH(Secure Shell 的缩写)是一种网络协议,用于加密两台计算机之间的通信,并且支持各种身份验证机制.还能对操作者进行认证(authentication)和授权(authorization ...

  7. [1.1W字] 复习: CSS 9个背景属性&6种渐变函数, 学会可以手写实现AI中强大的"任意渐变"! #Archives009

    Title/ CSS Background&Gradient完全指南 #Archives009 序: 关于 background 属性, 了解点CSS的人总会知道个大概. 但是你肯定多半还有点 ...

  8. CycliBarriar和CountdownLatch(计数器)

    CyclicBarrier可以重复使用,而CountdownLatch不能重复使用. countDownLatch这个类使一个线程等待其他线程各自执行完毕再执行. 是通过一个计数器来实现的,计数器的初 ...

  9. 如果被问到 HTTP 协议,你真的能讲清楚吗?

    前段时间,在和许久未见的老同学聊天时,突然被问到 http 协议到底是什么?脑海里面第一时间想起来的就是 request 请求.response 响应之类的词汇,但是这样讲他真的能知道是什么吗?我反问 ...

  10. springboot整合zookeeper实现分布式锁

    目录 01 安装并允许zookeeper 02 springboot应用配置CuratorFramework 03 使用zookeeper实现集群只一个应用实例执行定时任务 04 使用zookeepe ...