Thymeleaf学习

物理视图:

/pages/user/login.html

/pages/user/login_success.html

/pages/user/regist.html

/pages/user/regist_success.html

逻辑视图:

物理视图=视图前缀+逻辑视图+视图后缀

视图前缀

逻辑视图

视图后缀

物理视图

/pages/user/

login

.html

/pages/user/login.html

/pages/user/

login_success

.html

/pages/user/login_success.html

Thymeleaf需要入导入的jar包

配置上下文参数

物理视图=视图前缀+逻辑视图+视图后缀

<!-- 在上下文参数中配置视图前缀和视图后缀 -->
<context-param>
  <param-name>view-prefix</param-name>
  <param-value>/pages/</param-value>
</context-param>
<context-param>
  <param-name>view-suffix</param-name>
  <param-value>.html</param-value>
</context-param>

1.为什么要放在WEB-INF目录下?

原因:WEB-INF目录不允许浏览器直接访问,所以我们的视图模板文件放在这个目录下,是一种保护。以免外界可以随意访问视图模板文件。

2.访问WEB-INF目录下的页面,都必须通过Servlet转发过来,简单说就是:不经过Servlet访问不了。

这样就方便我们在Servlet中检查当前用户是否有权限访问。

3.那放在WEB-INF目录下之后,重定向进不去怎么办?

重定向到Servlet,再通过Servlet转发到WEB-INF下。

创建Servlet基类

package com.softeem.servlet;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import javax.servlet.ServletContext;
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.io.PrintWriter;

public class ViewBaseServlet extends HttpServlet {

    private TemplateEngine templateEngine;

    @Override
    public void init() throws ServletException {
        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();
        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);
        // ②设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");/* /pages */
        templateResolver.setPrefix(viewPrefix);
        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");/* .html */
        templateResolver.setSuffix(viewSuffix);
        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);
        // ⑤设置是否缓存
        templateResolver.setCacheable(true);//我是建议设置成false
        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");
        // 4.初始化模板引擎对象
        templateEngine = new TemplateEngine();
        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);
    }

    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");//输出流.向浏览器转出数据时防止乱码
        PrintWriter out = resp.getWriter();
        ServletContext servletContext = this.getServletContext();//容器上下文对象
        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req, resp, servletContext);
        // 3.处理模板数据
        templateEngine.process(templateName, webContext, out);
    }
}

过能Servlet请求转发访问与直接访问区别

<p th:text="张无忌">张三丰</p>

①th:text作用

  • 不经过服务器解析,直接用浏览器打开HTML文件,看到的是『张三丰』
  • 经过服务器解析,Thymeleaf引擎根据th:text属性指定的『张无忌』去替换『张三丰』

②字面量

『字面量』是一个经常会遇到的概念,我们可以对照『变量』来理解它的含义。

// a是变量,100是字面量
int a = 100;
System.out.println("a = " + a);
  • 变量:变量名字符串本身不是它的值,它指向的才是它的值
  • 字面量:它就是字面上的含义,我们从『字面』上看到的直接就是它的值

注意: 现在我们在th:text属性中使用的就是『字面量』,它不指代任何其他值

修改指定属性值

<input type="text" name="username" th:value="张无忌" value="张三丰" />

语法:任何HTML标签原有的属性,前面加上『th:』就都可以通过Thymeleaf来设定新值。

解析URL地址

@{/}的作用是在字符串前附加『上下文路径』

@{/}表示是你当然的项目名 /ThymeleafDemo


// 1.声明当前请求要前往的视图名称
String viewName = "target";
/*往req请求中保存一个属性
    名称:reqAttrName
    值: <span>hello-value</span>
 */
req.setAttribute("reqAttrName", "<span style='color:red'>hello-value</span>");

// 2.调用ViewBaseServlet父类中的解析视图模板的方法,此方法一定在最末尾处
super.processTemplate(viewName, req, resp);

<p>有转义效果:[[${reqAttrName}]]</p>
<p>无转义效果:[(${reqAttrName})]</p>
th:text效果<p th:text="${reqAttrName}"></p>
th:utext效果<p th:utext="${reqAttrName}"></p>

1、域对象

①请求域*****

在请求转发的场景下,我们可以借助HttpServletRequest对象内部给我们提供的存储空间,帮助我们携带数据,把数据发送给转发的目标资源。

通俗的说讲就是: 把服务中的数据传递到网页

我们使用request请求域来保存一些数据

@WebServlet("/RegionServlet")
public class RegionServlet extends ViewBaseServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.setAttribute("username" , "裴杰");
        req.setAttribute("password" , "123456");
        req.setAttribute("phone" , "13886082121");

        // 2.调用ViewBaseServlet父类中的解析视图模板的方法
        super.processTemplate("region", req, resp);

    }
}
 <h1>请求域测试取值</h1>
用户名:<input type="text" th:value="${username}"><br/>
密码:<input type="text" th:value="${password}"><br/>
手机:<input type="text" th:value="${phone}"><br/>
<div>[[${username}]]</div>
<div>[[${password}]]</div>
<div>[[${phone}]]</div>
<h1 th:text="${password}"></h1>
<h1 th:text="${username}"></h1>
<h1 th:text="${phone}"></h1>

请求域时间最短,范围也是最小的.一次请求内有效,请求完成.请求域中的数据就失效了

②会话域****

设置session的超时时间

<session-config>
  <!-- session超时,时间设置,默认就是30分钟.
  可以根据实际情况设置超时,时间长短-->
  <session-timeout>30</session-timeout>
</session-config>
//通过request对象获取HttpSession对象 : session
HttpSession session = req.getSession();
session.setAttribute("username" , "张三");
session.setAttribute("password" , "987654");
session.setAttribute("phone" , "13612345678");

    <h1>会话域测试取值</h1>
    用户名:<input type="text" th:value="${session.username}"><br/>
    密码:<input type="text" th:value="${session.password}"><br/>
    手机:<input type="text" th:value="${session.phone}"><br/>
    <div>[[${session.username}]]</div>
    <div>[[${session.password}]]</div>
    <div>[[${session.phone}]]</div>
    <h1 th:text="${session.password}"></h1>
    <h1 th:text="${session.username}"></h1>
    <h1 th:text="${session.phone}"></h1>

session会话域: 默认可以保存30分钟数据有效果,但是前提是不要关闭浏览器.如果关掉浏览器会在去访问.就访问不到session中的数据了.原因是跟cookie有关.但是我们现在还没有讲到cookie,我们后面讲完cookie会来解释失效的原因

③应用域(使用比较少)

//上下文对象 -> 应该域 -> 全局作用域
ServletContext servletContext = getServletContext();
servletContext.setAttribute("username" , "李四");
servletContext.setAttribute("password" , "101010");
servletContext.setAttribute("phone" , "1377777777");

页面取值时使用 ${application.xxxx} 这个application就是我们Serlvet类中的ServletContext对象

    <h1>应用域测试取值</h1>
    用户名:<input type="text" th:value="${application.username}"><br/>
    密码:<input type="text" th:value="${application.password}"><br/>
    手机:<input type="text" th:value="${application.phone}"><br/>
    <div>[[${application.username}]]</div>
    <div>[[${application.password}]]</div>
    <div>[[${application.phone}]]</div>
    <h1 th:text="${application.password}"></h1>
    <h1 th:text="${application.username}"></h1>
    <h1 th:text="${application.phone}"></h1>


应该域生命周期更长 他是与服务器生命一样长.只要服务器不关.保存到应该域中的数据会一直有效,直到你关闭服务器.[人在塔在] --> [服务器在应该域]

页面也能获取请求参数

<a href="RequestParamServlet?username=tom">请求参数测试</a><br/>

package com.softeem.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/RequestParamServlet")
public class RequestParamServlet extends ViewBaseServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");//解决post乱码
        //获取请求参数param
        String username = req.getParameter("username");
        System.out.println("username = " + username);
        //跳转页面pages/param.html
        super.processTemplate("param" , req ,resp);
    }
}

<body>
<h1>我是param网页</h1>
<p th:text="${param.username}">这里替换为请求参数的值</p>
</body>

效果图:

接收到参数tom

如果接收的请求参数为空字符 或者 null

请求时传入了username参数,但是此参数并且没有数据,此时服务端接收的是一个空字符串,在页面接收此username参数时,是不显示任何结果的

请求时没有传入了username参数,此时服务端接收的是null,在页面接收此username参数时,也是不显示任何结果的

一个参数多个值

    <a href="RequestParamServlet?hobby=足球&hobby=篮球&hobby=排球">请求参数[多个值]测试</a><br/>

package com.softeem.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

@WebServlet("/RequestParamServlet")
public class RequestParamServlet extends ViewBaseServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");//解决post乱码
        //获取请求参数param
        String username = req.getParameter("username");
        System.out.println("username = " + username);
        //一个参数多个值.取值时要使用getParameterValues()方法
        //如果还使用getParameter()方法,只能获取第一个值,后面其它时获取不到
        String[] hobby = req.getParameterValues("hobby");
        System.out.println(Arrays.toString(hobby));
        //跳转页面pages/param.html
        super.processTemplate("param" , req ,resp);
    }
}

可以通过下标的方式来取值

<p th:text="${param.hobby[0]}">这里替换为请求参数的值</p>
<p th:text="${param.hobby[1]}">这里替换为请求参数的值</p>
<p th:text="${param.hobby[2]}">这里替换为请求参数的值</p>

加入log4j.properties日志文件,放到src目录下

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:\\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout

内置对象

#request

<h3>表达式的基本内置对象</h3>
<p th:text="${#request.getClass().getName()}">这里显示#request对象的全类名</p>
<p th:text="${#request.getContextPath()}">调用#request对象的getContextPath()方法</p>
<p th:text="${#request.getAttribute('helloRequestAttr')}">调用#request对象的getAttribute()方法,读取属性域</p>

基本思路:
  • 如果不清楚这个对象有哪些方法可以使用,那么就通过getClass().getName()获取全类名,再回到Java环境查看这个对象有哪些方法
  • 内置对象的方法可以直接调用
  • 调用方法时需要传参的也可以直接传入参数

公共内置对象

#lists

req.setAttribute("aNotEmptyList", Arrays.asList("aaa","bbb","ccc"));
req.setAttribute("anEmptyList", new ArrayList<>());
<h1>#lists使用</h1>
<p>#list对象isEmpty方法判断集合整体是否为空aNotEmptyList:
    <span th:text="${#lists.isEmpty(aNotEmptyList)}">测试#lists</span></p>
<p>#list对象isEmpty方法判断集合整体是否为空anEmptyList:
    <span th:text="${#lists.isEmpty(anEmptyList)}">测试#lists</span></p>
<p>#lists对象contains方法判断集合中是否有aaa:
    <span th:text="${#lists.contains(aNotEmptyList , 'aaa')}"></span>
</p>
<p>#lists对象size方法,获取集合中的元素个数
    <span th:text="${#lists.size(aNotEmptyList)}"></span>
</p>

基本语法:${}中的表达式本质是OGNL

实验需要用到的类
package com.softeem.bean;

public class Teacher {
    private String teacherName;


    public Teacher() {
    }

    public Teacher(String teacherName) {
        this.teacherName = teacherName;
    }

    /**
     * 获取
     * @return teacherName
     */
    public String getTeacherName() {
        return teacherName;
    }

    /**
     * 设置
     * @param teacherName
     */
    public void setTeacherName(String teacherName) {
        this.teacherName = teacherName;
    }

    public String toString() {
        return "Teacher{teacherName = " + teacherName + "}";
    }
}
package com.softeem.bean;

public class Subject {
    private String subjectName;

    public Subject() {
    }

    public Subject(String subjectName) {
        this.subjectName = subjectName;
    }

    /**
     * 获取
     * @return subjectName
     */
    public String getSubjectName() {
        return subjectName;
    }

    /**
     * 设置
     * @param subjectName
     */
    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }

    public String toString() {
        return "Subject{subjectName = " + subjectName + "}";
    }
}
package com.softeem.bean;

public class School {
    private String schoolName ;


    public School() {
    }

    public School(String schoolName) {
        this.schoolName = schoolName;
    }

    /**
     * 获取
     * @return schoolName
     */
    public String getSchoolName() {
        return schoolName;
    }

    /**
     * 设置
     * @param schoolName
     */
    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }

    public String toString() {
        return "School{schoolName = " + schoolName + "}";
    }
}
package com.softeem.bean;

import java.util.List;
import java.util.Map;

public class Student {
    private String studentName;
    private Subject subject ;
    private List<School> schoolList;
    private Map<String,Teacher> teacherMap;


    public Student() {
    }

    public Student(String studentName, Subject subject, List<School> schoolList, Map<String, Teacher> teacherMap) {
        this.studentName = studentName;
        this.subject = subject;
        this.schoolList = schoolList;
        this.teacherMap = teacherMap;
    }

    /**
     * 获取
     * @return studentName
     */
    public String getStudentName() {
        return studentName;
    }

    /**
     * 设置
     * @param studentName
     */
    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    /**
     * 获取
     * @return subject
     */
    public Subject getSubject() {
        return subject;
    }

    /**
     * 设置
     * @param subject
     */
    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    /**
     * 获取
     * @return schoolList
     */
    public List<School> getSchoolList() {
        return schoolList;
    }

    /**
     * 设置
     * @param schoolList
     */
    public void setSchoolList(List<School> schoolList) {
        this.schoolList = schoolList;
    }

    /**
     * 获取
     * @return teacherMap
     */
    public Map<String, Teacher> getTeacherMap() {
        return teacherMap;
    }

    /**
     * 设置
     * @param teacherMap
     */
    public void setTeacherMap(Map<String, Teacher> teacherMap) {
        this.teacherMap = teacherMap;
    }

    public String toString() {
        return "Student{studentName = " + studentName + ", subject = " + subject + ", schoolList = " + schoolList + ", teacherMap = " + teacherMap + "}";
    }
}

网页取值演示代码:

<h1>属性访问语法测试</h1>
<!-- 也可以调用setStudentName()方法给学生名赋值 -->
<span th:text="${s.setStudentName('小芳')}"></span>

学生姓名:<span th:text="${s.studentName}"></span>
<span th:text="${s.getStudentName()}"></span><br/>

主题名:<span th:text="${s.subject.subjectName}"></span>
<span th:text="${s.getSubject().getSubjectName()}"></span><br/>

学校名:<span th:text="${s.schoolList[0].schoolName}"></span>
<span th:text="${s.schoolList[1].schoolName}"></span>
<span th:text="${s.schoolList[2].schoolName}"></span>
<span th:text="${s.getSchoolList().get(0).getSchoolName()}"></span>
<span th:text="${s.getSchoolList().get(1).getSchoolName()}"></span>
<span th:text="${s.getSchoolList().get(2).getSchoolName()}"></span><br/>

<!-- map使用方法取值不演示了.一样的操作流程 -->
老师名:<span th:text="${s.teacherMap.A1.teacherName}"></span>
<span th:text="${s.teacherMap.B2.teacherName}"></span>
<span th:text="${s.teacherMap['A1'].teacherName}"></span>
<span th:text="${s.teacherMap['B2'].teacherName}"></span>

取值效果如图:

关于怎么访问类中私有属性的问题?

分支与迭代

1、分支*****

①if

示例的实体类:

package com.softeem.bean;

public class Employee {

    private Integer empId;
    private String empName;
    private Double empSalary;


    public Employee() {
    }

    public Employee(Integer empId, String empName, Double empSalary) {
        this.empId = empId;
        this.empName = empName;
        this.empSalary = empSalary;
    }

    /**
     * 获取
     * @return empId
     */
    public Integer getEmpId() {
        return empId;
    }

    /**
     * 设置
     * @param empId
     */
    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    /**
     * 获取
     * @return empName
     */
    public String getEmpName() {
        return empName;
    }

    /**
     * 设置
     * @param empName
     */
    public void setEmpName(String empName) {
        this.empName = empName;
    }

    /**
     * 获取
     * @return empSalary
     */
    public Double getEmpSalary() {
        return empSalary;
    }

    /**
     * 设置
     * @param empSalary
     */
    public void setEmpSalary(Double empSalary) {
        this.empSalary = empSalary;
    }

    public String toString() {
        return "Employee{empId = " + empId + ", empName = " + empName + ", empSalary = " + empSalary + "}";
    }
}
package com.softeem.servlet;



import com.softeem.bean.Employee;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/BranchServlet")
public class BranchServlet extends ViewBaseServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.创建ArrayList对象并填充
        List<Employee> employeeList = new ArrayList<>();

        employeeList.add(new Employee(1, "tom", 500.00));
        employeeList.add(new Employee(2, "jerry", 600.00));
        employeeList.add(new Employee(3, "harry", 700.00));
        employeeList.add(new Employee(4, "张三", 800.00));
        employeeList.add(new Employee(5, "李四", 900.00));

        // 2.将集合数据存入请求域
        req.setAttribute("employeeList", employeeList);

        // 3.调用父类方法渲染视图
        super.processTemplate("branch", req, resp);
    }
}
<h2>分支if</h2>
<table border="1">
    <tr>
        <th>员工编号</th>
        <th>员工姓名</th>
        <th>员工工资</th>
    </tr>
    <tr th:if="${#lists.isEmpty(employeeList)}">
        <td colspan="3">抱歉!没有查询到你搜索的数据!</td>
    </tr>
    <tr th:if="${not #lists.isEmpty(employeeList)}">
        <td colspan="3">if我是有数据的!</td>
    </tr>
    <tr th:unless="${#lists.isEmpty(employeeList)}">
        <td colspan="3">unless有数据!</td>
    </tr>
</table>

演示效果如图:

②switch

在添加一个User类

package com.softeem.bean;

public class User {
    private String username ;//会员姓名
    private String memberLevel;//会员等级

    public User() {
    }

    public User(String username, String memberLevel) {
        this.username = username;
        this.memberLevel = memberLevel;
    }

    /**
     * 获取
     * @return username
     */
    public String getUsername() {
        return username;
    }

    /**
     * 设置
     * @param username
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * 获取
     * @return memberLevel
     */
    public String getMemberLevel() {
        return memberLevel;
    }

    /**
     * 设置
     * @param memberLevel
     */
    public void setMemberLevel(String memberLevel) {
        this.memberLevel = memberLevel;
    }

    public String toString() {
        return "User{username = " + username + ", memberLevel = " + memberLevel + "}";
    }
}

BranchServlet类中的service方法添加代码

User user = new User("小黄" , "level-3");
req.setAttribute("user" , user);
<h2>分支switch</h2>
<h3>测试switch</h3>
<div th:switch="${user.memberLevel}">
    [[${user.username}]]
    <p th:case="level-1">银牌会员</p>
    <p th:case="level-2">金牌会员</p>
    <p th:case="level-3">白金会员</p>
    <p th:case="level-4">钻石会员</p>
</div>

效果如图:

2、迭代*****

<h3>测试each</h3>
<table border="1">
    <thead>
    <tr>
        <th>员工编号</th>
        <th>员工姓名</th>
        <th>员工工资</th>
        <th>下标</th>
        <th>数量</th>
        <th>大小</th>
        <th>当前对象</th>
        <th>奇数</th>
        <th>偶数</th>
        <th>第一个</th>
        <th>最后一个</th>
    </tr>
    </thead>
    <tbody th:if="${#lists.isEmpty(employeeList)}">
    <tr>
        <td colspan="3">抱歉!没有查询到你搜索的数据!</td>
    </tr>
    </tbody>
    <tbody th:if="${not #lists.isEmpty(employeeList)}">
    <!-- 遍历出来的每一个元素的名字 : ${要遍历的集合} -->
    <tr th:each="emp,empStatus : ${employeeList}">
        <td th:text="${emp.empId}">empId</td>
        <td th:text="${emp.empName}">empName</td>
        <td th:text="${emp.empSalary}">empSalary</td>
          <!--以下代码是这个集合状态代码不是每次遍历数据都会有用
            一般是根据我们的需要使用.不会像我们现在这样全部显示出来-->
        <td th:text="${empStatus.index}">empSalary</td>
        <td th:text="${empStatus.count}">empSalary</td>
        <td th:text="${empStatus.size}">empSalary</td>
        <td th:text="${empStatus.current}">empSalary</td>
        <td th:text="${empStatus.even}">empSalary</td>
        <td th:text="${empStatus.odd}">empSalary</td>
        <td th:text="${empStatus.first}">empSalary</td>
        <td th:text="${empStatus.last}">empSalary</td>
    </tr>
    </tbody>
</table>

效果如图:

基本语法:包含其他模板文件

创建MainServlet类

package com.softeem.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/MainServlet")
public class MainServlet extends ViewBaseServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.processTemplate("main",req,resp);
    }
}

创建common.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div th:fragment="header" style="border: 2px red solid">
    <p>被抽取出来的头部内容</p>
</div>

<div th:fragment="tail" style="border: 2px blue dashed">
    <p>被抽取出来的尾部内容...</p>
</div>

<div th:fragment="left" style="border: 2px pink double">
    <p>被抽取出来的左则边内容...</p>
</div>

</body>
</html>

创建main.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!-- 代码片段所在页面的逻辑视图 :: 代码片段的名称 -->
<div id="badBoy" th:insert="common :: header" style="border: 2px greenyellow solid">
    div标签的原始内容
</div>

<h1>我是一个main.html</h1>

<div id="worseBoy" th:replace="common :: tail" style="border: 2px greenyellow solid">
    div标签的原始内容
</div>

<div id="testBoy" th:include="common :: left" style="border: 2px greenyellow solid">
    div标签的原始内容
</div>
</body>
</html>

效果如图:

网页源码部分:

玩转 CRUD

1、建模

①物理建模

CREATE DATABASE `view-demo`CHARACTER SET utf8;
USE `view-demo`;
CREATE TABLE t_soldier(
    soldier_id INT PRIMARY KEY AUTO_INCREMENT,
    soldier_name VARCHAR(100),
    soldier_weapon VARCHAR(100)
);

创建一个新的项目.结构与jar包,还有有工具类如图:

②逻辑建模

package com.softeem.bean;

public class Soldier {
    private Integer soldierId;
    private String soldierName;
    private String soldierWeapon;

    public Soldier() {
    }

    public Soldier(Integer soldierId, String soldierName, String soldierWeapon) {
        this.soldierId = soldierId;
        this.soldierName = soldierName;
        this.soldierWeapon = soldierWeapon;
    }

    /**
     * 获取
     * @return soldierId
     */
    public Integer getSoldierId() {
        return soldierId;
    }

    /**
     * 设置
     * @param soldierId
     */
    public void setSoldierId(Integer soldierId) {
        this.soldierId = soldierId;
    }

    /**
     * 获取
     * @return soldierName
     */
    public String getSoldierName() {
        return soldierName;
    }

    /**
     * 设置
     * @param soldierName
     */
    public void setSoldierName(String soldierName) {
        this.soldierName = soldierName;
    }

    /**
     * 获取
     * @return soldierWeapon
     */
    public String getSoldierWeapon() {
        return soldierWeapon;
    }

    /**
     * 设置
     * @param soldierWeapon
     */
    public void setSoldierWeapon(String soldierWeapon) {
        this.soldierWeapon = soldierWeapon;
    }

    public String toString() {
        return "Soldier{soldierId = " + soldierId + ", soldierName = " + soldierName + ", soldierWeapon = " + soldierWeapon + "}";
    }
}

2、总体架构

3、搭建持久化层所需环境

①导入jar包

attoparser-2.0.5.RELEASE.jar
commons-dbutils-1.7.jar
commons-logging-1.1.1.jar
druid-1.1.10.jar
hamcrest-core-1.3.jar
javassist-3.20.0-GA.jar
junit-4.12.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.37.jar
ognl-3.1.26.jar
servlet-api.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
thymeleaf-3.0.12.RELEASE.jar
unbescape-1.1.6.RELEASE.jar

②创建jdbc.properties

username=root
password=123456
url=jdbc:mysql://localhost:3306/view-demo?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true
driverClassName=com.mysql.jdbc.Driver

initialSize=5
maxActive=10

③配置web.xml

    <!-- 在上下文参数中配置视图前缀和视图后缀 -->
    <context-param>
        <param-name>view-prefix</param-name>
        <param-value>/WEB-INF/view/</param-value>
    </context-param>
    <context-param>
        <param-name>view-suffix</param-name>
        <param-value>.html</param-value>
    </context-param>

④创建view目录

6、显示首页

①目标

浏览器访问index.html,通过首页Servlet,渲染视图,显示首页。

②思路

③代码

[1]创建PortalServlet
package com.softeem.servlet;

import com.softeem.utils.ViewBaseServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/index.html")
public class PortalServlet extends ViewBaseServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String viewName = "portal";
        super.processTemplate(viewName, req, resp);
    }

}

说明:为什么我要把PortalServlet的url设置成index.html?

我们访问index.html网页还要去点击连接请求一个Servlet类.在使用servlet类帮我们进行请求转发.这样做还会多一次点击连接的操作.

所以我们干脆把servlet类起个名字[url]就叫做index.html.这样服务启动后直接就访问的是Servlet类.直接就可以请求转发到我们想去的网页.少了一次点击的过程

[2]创建portal.html

portal.html网页

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>士兵信息管理系统</title>
</head>
<body>
<a th:href="@{/SoldierServlet?method=showList}">显示士兵信息列表</a>
</body>
</html>
package com.softeem.utils;

import javax.servlet.ServletException;
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 ModelBaseServlet extends ViewBaseServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决post请求乱码
        req.setCharacterEncoding("utf-8");
        //获取一个请求参数.只参数是方法
        String method = req.getParameter("method");
        //获取当前类的.类描述对象,回去想一下this是谁???
        Class claxx = this.getClass();

        try {
            //获取要请求的方法对象
            Method declaredMethod = claxx.getDeclaredMethod(method HttpServletRequest.class, HttpServletResponse.class);

            declaredMethod.setAccessible(true);//关闭访问权限检查

            declaredMethod.invoke(this , req,resp);//执行方法

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
package com.softeem.servlet;

import com.softeem.utils.ModelBaseServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/SoldierServlet")
public class SoldierServlet extends ModelBaseServlet {


    protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SoldierServlet.add");
    }
    protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SoldierServlet.update");
    }
    protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SoldierServlet.delete");
    }
    protected void find(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SoldierServlet.find");
    }
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>士兵信息管理系统</title>
</head>
<body>
<!--<a th:href="@{/SoldierServlet?method=showList}">显示士兵信息列表</a>-->

<a th:href="@{/SoldierServlet?method=add}">显示士兵信息列表添加</a>
<a th:href="@{/SoldierServlet?method=update}">显示士兵信息列表修改</a>
<a th:href="@{/SoldierServlet?method=delete}">显示士兵信息列表删除</a>
<a th:href="@{/SoldierServlet?method=find}">显示士兵信息列表查询</a>
</body>
</html>

现在我们后端代码的执行流程1

现在我们后端代码的执行流程2

士兵管理的查询功能

t_soldier表多添加了三个字段.为我后续实现多条件分页查询做准备

javaBean重新生成一下

package com.softeem.bean;

import java.sql.Date;

public class Soldier {
    private Integer soldierId;
    private String soldierName;
    private String soldierWeapon;
    private String soldierSex;
    private Integer soldierAge;
    private Date soldierBirthday;


    public Soldier() {
    }

    public Soldier(Integer soldierId, String soldierName, String soldierWeapon, String soldierSex, Integer soldierAge, Date soldierBirthday) {
        this.soldierId = soldierId;
        this.soldierName = soldierName;
        this.soldierWeapon = soldierWeapon;
        this.soldierSex = soldierSex;
        this.soldierAge = soldierAge;
        this.soldierBirthday = soldierBirthday;
    }

    /**
     * 获取
     * @return soldierId
     */
    public Integer getSoldierId() {
        return soldierId;
    }

    /**
     * 设置
     * @param soldierId
     */
    public void setSoldierId(Integer soldierId) {
        this.soldierId = soldierId;
    }

    /**
     * 获取
     * @return soldierName
     */
    public String getSoldierName() {
        return soldierName;
    }

    /**
     * 设置
     * @param soldierName
     */
    public void setSoldierName(String soldierName) {
        this.soldierName = soldierName;
    }

    /**
     * 获取
     * @return soldierWeapon
     */
    public String getSoldierWeapon() {
        return soldierWeapon;
    }

    /**
     * 设置
     * @param soldierWeapon
     */
    public void setSoldierWeapon(String soldierWeapon) {
        this.soldierWeapon = soldierWeapon;
    }

    /**
     * 获取
     * @return soldierSex
     */
    public String getSoldierSex() {
        return soldierSex;
    }

    /**
     * 设置
     * @param soldierSex
     */
    public void setSoldierSex(String soldierSex) {
        this.soldierSex = soldierSex;
    }

    /**
     * 获取
     * @return soldierAge
     */
    public Integer getSoldierAge() {
        return soldierAge;
    }

    /**
     * 设置
     * @param soldierAge
     */
    public void setSoldierAge(Integer soldierAge) {
        this.soldierAge = soldierAge;
    }

    /**
     * 获取
     * @return soldierBirthday
     */
    public Date getSoldierBirthday() {
        return soldierBirthday;
    }

    /**
     * 设置
     * @param soldierBirthday
     */
    public void setSoldierBirthday(Date soldierBirthday) {
        this.soldierBirthday = soldierBirthday;
    }

    public String toString() {
        return "Soldier{soldierId = " + soldierId + ", soldierName = " + soldierName + ", soldierWeapon = " + soldierWeapon + ", soldierSex = " + soldierSex + ", soldierAge = " + soldierAge + ", soldierBirthday = " + soldierBirthday + "}";
    }
}

SoldierDao接口

package com.softeem.dao;

import com.softeem.bean.Soldier;
import java.util.List;

public interface SoldierDao {

    List<Soldier> selectSoldierList();

}

SoldierDaoImpl实现

package com.softeem.dao.impl;

import com.softeem.bean.Soldier;
import com.softeem.dao.SoldierDao;
import com.softeem.utils.BaseDao;
import java.util.List;

public class SoldierDaoImpl extends BaseDao<Soldier> implements SoldierDao {

    @Override
    public List<Soldier> selectSoldierList() {
        return super.getBeanList("select * from t_soldier");
    }

}

SoldierService接口

package com.softeem.service;

import com.softeem.bean.Soldier;

import java.util.List;

public interface SoldierService {

    List<Soldier> getSoldierList();

}

SoldierServiceImpl实现

package com.softeem.service.impl;

import com.softeem.bean.Soldier;
import com.softeem.dao.SoldierDao;
import com.softeem.dao.impl.SoldierDaoImpl;
import com.softeem.service.SoldierService;

import java.util.List;

public class SoldierServiceImpl implements SoldierService {

    private SoldierDao soldierDao = new SoldierDaoImpl();

    @Override
    public List<Soldier> getSoldierList() {
        return soldierDao.selectSoldierList();
    }
}

SoldierServlet

package com.softeem.servlet;

import com.softeem.bean.Soldier;
import com.softeem.service.SoldierService;
import com.softeem.service.impl.SoldierServiceImpl;
import com.softeem.utils.ModelBaseServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/SoldierServlet")
public class SoldierServlet extends ModelBaseServlet {

    protected void showList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建业务层对象:soldierService
        SoldierService soldierService = new SoldierServiceImpl() ;
        // 1.调用Service方法获取集合数据
        List<Soldier> soldierList = soldierService.getSoldierList();
        for (Soldier soldier : soldierList) {
            System.out.println("soldier = " + soldier);
        }
        // 2.将集合数据存入请求域
        req.setAttribute("soldierList" ,soldierList);
        // 3.渲染视图(在渲染的过程中,已经包含了转发)
        super.processTemplate("list" ,req,resp);
    }
}

list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1">
    <tr>
        <th>士兵编号</th>
        <th>士兵姓名</th>
        <th>士兵武器</th>
        <th>士兵性别</th>
        <th>士兵年龄</th>
        <th>士兵生日</th>
    </tr>
    <tr th:each="soldier : ${soldierList}">
        <td th:text="${soldier.soldierId}"></td>
        <td th:text="${soldier.soldierName}"></td>
        <td th:text="${soldier.soldierWeapon}"></td>
        <td th:text="${soldier.soldierSex}"></td>
        <td th:text="${soldier.soldierAge}"></td>
        <td th:text="${soldier.soldierBirthday}"></td>
    </tr>
</table>
</body>
</html>

BaseDao中的4个方法.开始驼峰转换,否则不法获取数据

 /**
     * 获取所有对象
     *
     * @param sql
     * @param params
     * @return
     */
    public List<T> getBeanList(Connection conn, String sql, Object... params) {
        List<T> list = null;
        try {
            //开启下划线->驼峰转换所用
            BeanProcessor bean = new GenerousBeanProcessor();
            RowProcessor processor = new BasicRowProcessor(bean);
            list = queryRunner.query(conn, sql, new BeanListHandler<T>(type,processor), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取所有对象
     *
     * @param sql
     * @param params
     * @return
     */
    public List<T> getBeanList( String sql, Object... params) {
        List<T> list = null;
        try {
            //开启下划线->驼峰转换所用
            BeanProcessor bean = new GenerousBeanProcessor();
            RowProcessor processor = new BasicRowProcessor(bean);
            list = queryRunner.query( sql, new BeanListHandler<T>(type,processor), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取一个对象
     *
     * @param sql
     * @param params
     * @return
     */
    public T getBean(Connection conn,String sql, Object... params) {
        T t = null;
        try {                                              //type == String.class
            //开启下划线->驼峰转换所用
            BeanProcessor bean = new GenerousBeanProcessor();
            RowProcessor processor = new BasicRowProcessor(bean);
            t = queryRunner.query(conn, sql, new BeanHandler<T>(type,processor), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return t;
    }
    /**
     * 获取一个对象
     *
     * @param sql
     * @param params
     * @return
     */
    public T getBean(String sql, Object... params) {
        T t = null;
        try {                                              //type == String.class
            //开启下划线->驼峰转换所用
            BeanProcessor bean = new GenerousBeanProcessor();
            RowProcessor processor = new BasicRowProcessor(bean);
            t = queryRunner.query( sql, new BeanHandler<T>(type,processor), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return t;
    }

前往修改信息的表单页面

两种不同的传参方法,语法不同.但是效果是一样的

<a th:href="@{SoldierServlet(soldierId=${soldier.soldierId},method=toEditPage)}">编辑</a>
<a th:href="@{'SoldierServlet?soldierId='+${soldier.soldierId}+'&method=toEditPage'}">编辑</a>

SoldierDao接口增加方法

Soldier findById(String soldierId);

SoldierDaoImpl实现类增加方法

@Override
public Soldier findById(String soldierId) {
    return super.getBean("select * from t_soldier where soldier_id = ?" , soldierId);
}

SoldierService接口增加方法

 Soldier getSoldierById(String soldierId);

SoldierServiceImpl实现类增加方法

@Override
public Soldier getSoldierById(String soldierId) {
    return soldierDao.findById(soldierId);
}

SoldierServlet类添加方法

protected void toEditPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1获取客户端提交上来的士兵主键id
        String soldierId = req.getParameter("soldierId");
        //2业务层对象根据主键id去查询此士兵的信息,返回一个士兵对象
        SoldierService soldierService = new SoldierServiceImpl();
        Soldier soldier = soldierService.getSoldierById(soldierId);
        //把soldier对象保存到req请求域对象中,传到网页中去
        req.setAttribute("soldier" , soldier);
        //跳传到edit-page网页,并且携带了soldier对象
        super.processTemplate("edit-page" ,req,resp);
    }

日期这儿我们使用一个js控制..不要用户自己输入日期.用户输入的日期可能不符合我们的格式要求

My97日期控件官方网站 My97 DatePicker

<base th:href="@{/}">
<!-- 引入日期控件的js文件 -->
<script language="javascript" type="text/javascript" th:src="@{My97DatePicker/WdatePicker.js}"></script>

input元素使用日期控件

<tr>
  <td>士兵生日:</td>
  <td><input type="text" name="soldierBirthday" th:value="${soldier.soldierBirthday}" onclick="WdatePicker({el:this,dateFmt:'yyyy-MM-dd'})"></td>
</tr>

SoldierDao接口增加方法

   void updateById(Soldier soldier);

SoldierDaoImpl实现类增加方法

@Override
public void updateById(Soldier soldier) {
	String sql = "update t_soldier set soldier_name=?,soldier_weapon=?,soldier_sex=?,soldier_age=?,soldier_birthday=? where soldier_id=?";
	super.update(sql,soldier.getSoldierName(),soldier.getSoldierWeapon(),soldier.getSoldierSex(),
                soldier.getSoldierAge(),soldier.getSoldierBirthday(),soldier.getSoldierId());
}

SoldierService接口增加方法

void updateSoldier(Soldier soldier);

SoldierServiceImpl实现类增加方法

    @Override
    public void updateSoldier(Soldier soldier) {
        soldierDao.updateById(soldier);
    }

SoldierServlet类添加方法

protected void updateSoldier(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, ParseException {
        // 1.获取请求参数
        String soldierId = req.getParameter("soldierId");
        String soldierName = req.getParameter("soldierName");
        String soldierWeapon = req.getParameter("soldierWeapon");
        String soldierSex = req.getParameter("soldierSex");
        String soldierAge = req.getParameter("soldierAge");
        String soldierBirthday = req.getParameter("soldierBirthday");

        // 2.封装对象
        Soldier soldier = new Soldier();
        soldier.setSoldierId(Integer.parseInt(soldierId));
        soldier.setSoldierName(soldierName);
        soldier.setSoldierWeapon(soldierWeapon);
        soldier.setSoldierSex(soldierSex);
        if(soldierAge!=null && !soldierAge.equals("")){
            soldier.setSoldierAge(Integer.parseInt(soldierAge));
        }
        //非null and 非空串 才能执行if里面的代码
        if(soldierBirthday!=null && !soldierBirthday.equals("")){
            //创建一个日期格式解析器对象
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //将字符串转换成一个日期对象: date
            Date date = sdf.parse(soldierBirthday);
            //把util包下的date对象转换成了sql包下的date对象
            soldier.setSoldierBirthday(new java.sql.Date(date.getTime()));
        }
        //创建业务层对象:soldierService
        SoldierService soldierService = new SoldierServiceImpl();
        // 3.调用Service方法执行更新
        soldierService.updateSoldier(soldier);

        //不要直接跳转到list网页,因为你没有传递过去.list网页里面什么都不会显示,无意义
        //super.processTemplate("list" ,req ,resp);
        //这样调用showList方法.刷新网页时.会出现表单重复提交的问题
        //this.showList(req,resp);//调用showList,此方法会跳转到list网页并传递数据
        //如果想解决表单重复提交,我们可以使用重定向跳转的方式来解决此问题
        //req.getContextPath() 此方法可获取当前工程路径
        resp.sendRedirect(req.getContextPath() + "/SoldierServlet?method=showList");
        //注意前面不要加[/]斜杠,如果加了[/]斜杠.就变成了http://localhost:8080/SoldierServlet?method=showList
}

删除功能

SoldierDao接口增加方法

    void deleteById(String soldierId);

SoldierDaoImpl实现类增加方法

    @Override
    public void deleteById(String soldierId) {
        super.update("delete from t_soldier where soldier_id=?" , soldierId);
    }

SoldierService接口增加方法

    void remove(String soldierId);

SoldierServiceImpl实现类增加方法

    @Override
    public void remove(String soldierId) {
        soldierDao.deleteById(soldierId);
    }

SoldierServlet类添加方法

    protected void remove(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取请求参数
        String soldierId = req.getParameter("soldierId");
        //2.调用业务层方法
        SoldierService soldierService = new SoldierServiceImpl();
        soldierService.remove(soldierId);

        //req.getContextPath() 此方法可获取当前工程路径
        System.out.println("req.getContextPath() = " + req.getContextPath());
        //3.跳转到list网页
        resp.sendRedirect(req.getContextPath() + "/SoldierServlet?method=showList");
    }

list.html网页部分

 <a href="javascript:void(0)" th:onclick="'mydelete('+${soldier.soldierId}+')'">删除</a>

 <script>
    function mydelete(id){
        if(window.confirm("你确定删除此数据吗?")){
            window.location.href = "SoldierServlet?method=remove&soldierId="+id;
        }
    }
</script>

添加成能

📎add-page.html网页

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <base th:href="@{/}">
    <!-- 引入日期控件的js文件 -->
    <script type="text/javascript" th:src="@{My97DatePicker/WdatePicker.js}"></script>
</head>
<body>
<form th:action="@{SoldierServlet}" method="post">
    <input type="hidden" name="method" value="saveSoldier" />
    <table border="1">
        <tr>
            <td>士兵姓名:</td>
            <td><input type="text" name="soldierName"></td>
        </tr>
        <tr>
            <td>士兵武器:</td>
            <td><input type="text" name="soldierWeapon"></td>
        </tr>
        <tr>
            <td>士兵性别:</td>
            <td><input type="text" name="soldierSex"></td>
        </tr>
        <tr>
            <td>士兵年龄:</td>
            <td><input type="text" name="soldierAge"></td>
        </tr>
        <tr>
            <td>士兵生日:</td>
            <td><input type="text" name="soldierBirthday" onclick="WdatePicker({el:this,dateFmt:'yyyy-MM-dd'})"></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="添加">
            </td>
        </tr>
    </table>
</form>
</body>
</html>

SoldierDao接口添加方法

    void save(Soldier soldier);

SoldierDaoImpl实现类添加方法

    @Override
    public void save(Soldier soldier) {
        String sql = "insert into t_soldier values(null,?,?,?,?,?)";
        super.update(sql,soldier.getSoldierName(),soldier.getSoldierWeapon(),soldier.getSoldierSex(),soldier.getSoldierAge(),soldier.getSoldierBirthday());
    }

SoldierService接口增加方法

    void save(Soldier soldier);

SoldierServiceImpl实现类增加方法

    @Override
    public void save(Soldier soldier) {
        soldierDao.save(soldier);
    }

SoldierServlet类添加方法

 protected void saveSoldier(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, ParseException {
        // 1.获取请求参数
        String soldierName = req.getParameter("soldierName");
        String soldierWeapon = req.getParameter("soldierWeapon");
        String soldierSex = req.getParameter("soldierSex");
        String soldierAge = req.getParameter("soldierAge");
        String soldierBirthday = req.getParameter("soldierBirthday");

        // 2.封装对象
        Soldier soldier = new Soldier();
        soldier.setSoldierName(soldierName);
        soldier.setSoldierWeapon(soldierWeapon);
        soldier.setSoldierSex(soldierSex);
        if (soldierAge != null && !soldierAge.equals("")) {
            soldier.setSoldierAge(Integer.parseInt(soldierAge));
        }
        //非null and 非空串 才能执行if里面的代码
        if (soldierBirthday != null && !soldierBirthday.equals("")) {
            //创建一个日期格式解析器对象
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //将字符串转换成一个日期对象: date
            Date date = sdf.parse(soldierBirthday);
            //把util包下的date对象转换成了sql包下的date对象
            soldier.setSoldierBirthday(new java.sql.Date(date.getTime()));
        }
        //创建业务层对象:soldierService
        SoldierService soldierService = new SoldierServiceImpl();
        //保存soldier对象到数据库
        soldierService.save(soldier);
        //这样操作会出现表单重复提交问题,不要这样操作
        //this.showList(req,resp);
        //重定向的方式.可以很好的解决表单重复提交的问题
        resp.sendRedirect(req.getContextPath()+"/SoldierServlet?method=showList");
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值