javaweb一阶段-表单的管理系统(sgg)

已有的知识-jdbc(康师傅版)

先要知道tomcat的部署和配置

tomcat对外就是web服务器,对内是Servlet容器,在idea中关联上tomcat的话,就可以在idea中启动tomcat,然后访问我们的web项目了,而且通过start.bat打开和idea打开是不能同时存在的,开启一个的时候应该把前一个关闭

数据库就是mysql

Thymeleaf的相关知识

目录

各种配置------

开始看

先看一下整体的文件及配置情况

看一下具体的


各种配置------

一开始觉得实在是太繁琐了,总会有各种各样的错误,然后也不知道jar包应该放在什么地方更好,慢慢的跟着做的多次了,之后才有点感觉,在排除了那么多错误之后,才会对这些问题熟悉起来,jar包的话,可以在每个module里面自己建一个lib文件夹,然后放到里面再右键选择add...,也可以放到最下面那个地方,可以给全局使用,用到的时候引入就好了,这其中这这那那的需要注意的地方太多,只能通过在自己的不断的试错去解决,而且很多其实是细枝末节的地方,比如有的路径少写个0什么的。。。

开始看

先看一下整体的文件及配置情况

这是module里的所有文件

javaweb一阶段-表单的管理系统(sgg)_第1张图片javaweb一阶段-表单的管理系统(sgg)_第2张图片

右边的是lib里的jar包,里面除了连接数据库的驱动都是thymeleaf需要的,tomcat在其他地方引入的

javaweb一阶段-表单的管理系统(sgg)_第3张图片

 上面这个图就是引入情况

目前各方面更深入的情况还不是很了解

看一下具体的

想要沟通一个数据库的表,先来处理这一部分

创建表的类Fruit.class

package com.xue.fruit.pojo;

/**
 * @author xxx
 * @create 2022-04-16 22:10
 */

public class Fruit {
    private Integer fid ;
    private String fname ;
    private Integer price ;
    private Integer fcount ;
    private String remark ;

    public Fruit(){}

    public Fruit(Integer fid, String fname, Integer price, Integer fcount, String remark) {
        this.fid = fid;
        this.fname = fname;
        this.price = price;
        this.fcount = fcount;
        this.remark = remark;
    }

    public Integer getFid() {
        return fid;
    }

    public void setFid(Integer fid) {
        this.fid = fid;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public Integer getFcount() {
        return fcount;
    }

    public void setFcount(Integer fcount) {
        this.fcount = fcount;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return fid + "\t\t" + fname + "\t\t" + price +"\t\t" + fcount +"\t\t" + remark ;
    }
}

再创建一个接口 包含我们需要对表做的所有基本操作,其中的残数等等,在后面都是用得到的

package com.xue.fruit.dao;

import com.xue.fruit.pojo.Fruit;

import java.util.List;

/**
 * @author xxx
 * @create 2022-04-16 22:20
 */
public interface FruitDAO {

    //获取指定页码上的库存列表信息  每页显示5条
    List getFruitList(String keyword,Integer pageNo);


    //工具fid获取特定的水果库存信息
    Fruit getFruitByFid(Integer fid);

    //修改指定的库存记录
    void updateFruit(Fruit fruit);

    //根据fid删除指定的库存记录
    void delFruit(Integer fid);

    //添加新库存记录
    void addFruit(Fruit fruit);

    //查询库存总记录条数
    int getFruitCount(String keyword);


}

我们想要对数据库进行操作,当然还需要获取连接等等的一系列操作,如下持久化的DAO层

package com.xue.myssm.basedao;

/**
 *
 *
 * 配置DAO文件
 * 配置信息也在其中
 * 这个方法应该不咋好用
 * @author xxx
 * @create 2022-04-15 19:42
 */

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public abstract class BaseDAO {
    public final String DRIVER = "com.mysql.cj.jdbc.Driver" ;
    public final String URL = "jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&db_daily_management&serverTimezone=GMT&useSSL=false";
    public final String USER = "root";
    public final String PWD = "xzh520" ;


    protected Connection conn ;
    protected PreparedStatement psmt ;
    protected ResultSet rs ;

    //T的Class对象
    private Class entityClass ;

    public BaseDAO(){
        //getClass() 获取Class对象,当前我们执行的是new FruitDAOImpl() , 创建的是FruitDAOImpl的实例
        //那么子类构造方法内部首先会调用父类(BaseDAO)的无参构造方法
        //因此此处的getClass()会被执行,但是getClass获取的是FruitDAOImpl的Class
        //所以getGenericSuperclass()获取到的是BaseDAO的Class
        Type genericType = getClass().getGenericSuperclass();
        //ParameterizedType 参数化类型
        Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
        //获取到的中的T的真实的类型
        Type actualType = actualTypeArguments[0];
        try {
            entityClass = Class.forName(actualType.getTypeName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    protected Connection getConn(){
        try {
            //1.加载驱动
            Class.forName(DRIVER);
            //2.通过驱动管理器获取连接对象
            return DriverManager.getConnection(URL, USER, PWD);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return null ;
    }

    protected void close(ResultSet rs , PreparedStatement psmt , Connection conn){
        try {
            if (rs != null) {
                rs.close();
            }
            if(psmt!=null){
                psmt.close();
            }
            if(conn!=null && !conn.isClosed()){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    //给预处理命令对象设置参数
    private void setParams(PreparedStatement psmt , Object... params) throws SQLException {
        if(params!=null && params.length>0){
            for (int i = 0; i < params.length; i++) {
                psmt.setObject(i+1,params[i]);
            }
        }
    }

    //执行更新,返回影响行数
    protected int executeUpdate(String sql , Object... params){
        boolean insertFlag = false ;
        insertFlag = sql.trim().toUpperCase().startsWith("INSERT");
        try {
            conn = getConn();
            if(insertFlag){
                psmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
            }else {
                psmt = conn.prepareStatement(sql);
            }
            setParams(psmt,params);
            int count = psmt.executeUpdate() ;

            if(insertFlag){
                rs = psmt.getGeneratedKeys();
                if(rs.next()){
                    return ((Long)rs.getLong(1)).intValue();
                }
            }

            return count ;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(rs,psmt,conn);
        }
        return 0;
    }

    //通过反射技术给obj对象的property属性赋propertyValue值
    private void setValue(Object obj ,  String property , Object propertyValue){
        Class clazz = obj.getClass();
        try {
            //获取property这个字符串对应的属性名 , 比如 "fid"  去找 obj对象中的 fid 属性
            Field field = clazz.getDeclaredField(property);
            if(field!=null){
                field.setAccessible(true);
                field.set(obj,propertyValue);
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //执行复杂查询,返回例如统计结果
    protected Object[] executeComplexQuery(String sql , Object... params){
        try {
            conn = getConn() ;
            psmt = conn.prepareStatement(sql);
            setParams(psmt,params);
            rs = psmt.executeQuery();

            //通过rs可以获取结果集的元数据
            //元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等

            ResultSetMetaData rsmd = rs.getMetaData();
            //获取结果集的列数
            int columnCount = rsmd.getColumnCount();
            Object[] columnValueArr = new Object[columnCount];
            //6.解析rs
            if(rs.next()){
                for(int i = 0 ; i executeQuery(String sql , Object... params){
        List list = new ArrayList<>();
        try {
            conn = getConn() ;
            psmt = conn.prepareStatement(sql);
            setParams(psmt,params);
            rs = psmt.executeQuery();

            //通过rs可以获取结果集的元数据
            //元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等

            ResultSetMetaData rsmd = rs.getMetaData();
            //获取结果集的列数
            int columnCount = rsmd.getColumnCount();
            //6.解析rs
            while(rs.next()){
                T entity = (T)entityClass.newInstance();

                for(int i = 0 ; i

把接口还有对数据库的普通通用操作写好之后,就可以编写我们需要的功能

package com.xue.fruit.dao.impl;

import com.xue.fruit.dao.FruitDAO;
import com.xue.fruit.pojo.Fruit;
import com.xue.myssm.basedao.BaseDAO;

import java.util.List;

/**
 * @author xxx
 * @create 2022-04-16 22:21
 */
public class FruitImpl extends BaseDAO implements FruitDAO{


    @Override
    public List getFruitList(String keyword,Integer pageNo) {

        return super.executeQuery("select * from t_fruit where fname like ? or remark like ? limit ? , 5","%"+keyword+"%","%"+keyword+"%",(pageNo-1)*5);
    }



    @Override
    public Fruit getFruitByFid(Integer fid) {
        return super.load("select * from t_fruit where fid = ?",fid);
    }

    @Override
    public void updateFruit(Fruit fruit) {
        String sql = "update t_fruit set fname = ?,price = ?,fcount = ?,remark = ? where fid = ?";
        super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark(),fruit.getFid());


    }

    @Override
    public void delFruit(Integer fid) {
        super.executeUpdate("delete from t_fruit where fid = ?",fid);

    }

    @Override
    public void addFruit(Fruit fruit) {
        String sql = "insert into t_fruit values(0,?,?,?,?)";
        super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark());


    }

    @Override
    public int getFruitCount(String keyword) {
        //这个地方的转型 也很重要
        return ((Long) super.executeComplexQuery("select count(*) from t_fruit where fname like ? or remark like ?","%"+keyword+"%","%"+keyword+"%")[0]).intValue();
    }
}














对数据库的一部分梳理上面就完成了。

现在我们需要完成我们设想的web项目,那么就开始一步一步的增加功能,这里都是最终版的代码

先写一个首页index.html




    
    
    
    Title


欢迎使用水果库存系统

请输入查询关键字:
添加新库存记录
名称 单价 库存 操作
对不起,库存为空!
苹果 5 20

有了前端的页面之后想要沟通服务器与数据库 自然有Servlet,这里面有很多是一开始没有添加的代码

package com.xue.fruit.servlets;

import com.xue.fruit.dao.FruitDAO;
import com.xue.fruit.dao.impl.FruitImpl;
import com.xue.fruit.pojo.Fruit;
import com.xue.myssm.myspringmvc.ViewBaseServlet;
import com.xue.myssm.util.StringUtil;

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

/**
 * @author xxx
 * @create 2022-04-16 22:25
 */

//Servlet从3.0开始支持注解方式的注册  其实就把不同url对应的资源注册
@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
//请求是从浏览器发到我们的程序  响应是从我们的程序发给浏览器
//Servlet等于说就是服务器端的小程序
//Servlet主要负责处理请求、协调调度功能
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("UTF-8");
        //获取当前的会话session-----作用域问题
        HttpSession session = req.getSession();

        //设置当前页 默认值为1
        Integer pageNo = 1;


        //获取form表单中oper的值
        String oper = req.getParameter("oper");
        //如果oper!=null 说明 通过表单的查询按钮点击过来的
        //如果oper是空的,说明 不是通过表单的查询按钮点击过来的

        String keyword = null;//关键字 就查询的那个字
        if(StringUtil.isNotEmpty(oper)&&"search".equals(oper)){
            //说明是点击表单查询发送过来的请求
            //此时,pageNo应该还原为1,keyword应该从请求参数中获取
            pageNo = 1;//重新设置为1 新表的第一页
            keyword = req.getParameter("keyword");//从请求中获取关键字
            if(StringUtil.isEmpty(keyword)){//这个时候是点了查询但是其实没有写任何东西
                keyword = "";//所以再设为空 让他不null  不然的话查询的时候会拼接是%null%
            }
            session.setAttribute("keyword",keyword);//为session加入keyword
        }else{
            //说明此处不是点击表单查询发送过来的请求(比如上面的上一页下一页或者地址栏输入网址)
            //此时keyword应该从session作用域获取
            String pageNoStr=req.getParameter("pageNo");
            if(StringUtil.isNotEmpty(pageNoStr)){
                pageNo = Integer.parseInt(pageNoStr);
                //如果请求中读得到得时候就强转 如果读不到就有上面得1

            }
            //如果不是点击的查询按钮 那么查询是基于session中的保存的现有的keyword进行查询
            Object keywordObj = session.getAttribute("keyword");
            if(keywordObj!=null){
                keyword = (String)keywordObj;
            }else{
                keyword = "";//比如第一次进入网页的时候
            }


        }
        //反正已经分为了有内容得查询和无内容得查询

        //在作用域 重新更新当前页得值
        session.setAttribute("pageNo",pageNo);

        FruitDAO fruitDAO = new FruitImpl();
        //获取库存列表
        List fruitList = fruitDAO.getFruitList(keyword,pageNo);
        //保存到session中
        session.setAttribute("fruitList",fruitList);
        //获取总记录条数
        int fruitCount = fruitDAO.getFruitCount(keyword);
        //总条数  总页数
        //fruitCount  (fruitCount+5-1)/5
        int pageCount = (fruitCount+5-1)/5;

        session.setAttribute("pageCount",pageCount);
        //此处视图的名称是 index
        //那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图名称上去
        //物理视图=视图前缀+逻辑视图+视图后缀
        //逻辑视图名称  index
        //物理视图名称  view-prefix + 逻辑视图名称 + view-suffix
        //所以真实的视图名称就是  /  index  .html
        super.processTemplate("index",req,resp);


    }
}

还有增加列的界面,在次界面修改后,通过post方式提交到服务器,修改数据库的信息




    
    
    Title



新增库存信息3

名称:
单价:
库存:
备注:

跳转到add.do的服务器小程序,配置信息都可以写道xml但是这里没有写

package com.xue.fruit.servlets;

import com.xue.fruit.dao.FruitDAO;
import com.xue.fruit.dao.impl.FruitImpl;
import com.xue.fruit.pojo.Fruit;
import com.xue.myssm.myspringmvc.ViewBaseServlet;

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

/**
 * @author xxx
 * @create 2022-04-18 15:07
 */
@WebServlet("/add.do")
public class AddServlet extends ViewBaseServlet {

    private FruitDAO fruitDAO = new FruitImpl();


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //设置编码
        req.setCharacterEncoding("UTF-8");
        //获取数据
        String fname = req.getParameter("fname");
        Integer price = Integer.parseInt(req.getParameter("price"));
        Integer fcount = Integer.parseInt(req.getParameter("fcount"));
        String remark = req.getParameter("remark");

        Fruit fruit = new Fruit(0,fname,price,fcount,remark);

        fruitDAO.addFruit(fruit);

        resp.sendRedirect("index");

    }
}

还有修改信息的界面




    
    
    Title



编辑库存信息

名称:
单价:
库存:
备注:

然后转到updateServlet

package com.xue.fruit.servlets;

import com.xue.fruit.dao.FruitDAO;
import com.xue.fruit.dao.impl.FruitImpl;
import com.xue.fruit.pojo.Fruit;
import com.xue.myssm.myspringmvc.ViewBaseServlet;

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

/**
 * @author xxx
 * @create 2022-04-17 17:50
 */
@WebServlet("/update.do")
public class UpdateSevlet extends ViewBaseServlet{

    private FruitDAO fruitDAO = new FruitImpl();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.设置编码
        req.setCharacterEncoding("utf-8");
        //2.获取参数
        String fidStr = req.getParameter("fid");
        Integer fid = Integer.parseInt(fidStr);

        String fname = req.getParameter("fname");

        String priceStr = req.getParameter("price");
        Integer price = Integer.parseInt(priceStr);

        String fcountStr = req.getParameter("fcount");
        Integer fcount=Integer.parseInt(fcountStr);

        String remark = req.getParameter("remark");
        //3.执行更新
        fruitDAO.updateFruit(new Fruit(fid,fname,price,fcount,remark));
        //4.资源跳转
        //super.processTemplate("index",req,resp);
        //req.getRequestDispatcher("index.html").forward(req,resp);
        //此处需要重定向 目的是重新给IndexServlet发请求,重新获取fruitList,然后覆盖到session中,这样index.html页面显示的session中的数据才是最新的

        resp.sendRedirect("index");


    }
}

删除的

package com.xue.fruit.servlets;

import com.xue.fruit.dao.FruitDAO;
import com.xue.fruit.dao.impl.FruitImpl;
import com.xue.myssm.myspringmvc.ViewBaseServlet;
import com.xue.myssm.util.StringUtil;

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

/**
 * @author xxx
 * @create 2022-04-18 12:22
 */
@WebServlet("/del.do")
public class DelServlet extends ViewBaseServlet{
    private FruitDAO fruitDAO = new FruitImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String fidStr=req.getParameter("fid");
        if(StringUtil.isNotEmpty(fidStr)){
            int fid = Integer.parseInt(fidStr);
            fruitDAO.delFruit(fid);

            resp.sendRedirect("index");


        }
    }
}

基本的功能就完成

还需要一些配置类的文件

css

add.css

*{
    color: threeddarkshadow;
}
a{
    text-decoration: none;
}
body{
    margin:0;
    padding:0;
    background-color:#808080;
}
div{
    position:relative;
    float:left;
}

#div_container{
    width:80%;
    height:100%;
    border:0px solid blue;
    margin-left:10%;
    float:left;
    background-color: honeydew;
    border-radius:8px;
}
#div_fruit_list{
    width:100%;
    border:0px solid red;
}
#tbl_fruit{
    width:60%;
    line-height:28px;
    margin-top:16px;
    margin-left:20%;
}
#tbl_fruit , #tbl_fruit tr , #tbl_fruit th , #tbl_fruit td{
    border:1px solid gray;
    border-collapse:collapse;
    text-align:center;
    font-size:16px;
    font-family:"黑体";
    font-weight:lighter;

}
.w20{
    width:20%;
}
.delImg{
    width:24px;
    height:24px;
}
.btn{
    border:1px solid lightgray;
    width:80px;
    height:24px;
}

.center{
    text-align:center;
}
.f30{
    font-size: 30px;
}

edit.css

*{
    color: threeddarkshadow;
}
a{
    text-decoration: none;
}
body{
    margin:0;
    padding:0;
    background-color:#808080;
}
div{
    position:relative;
    float:left;
}

#div_container{
    width:80%;
    height:100%;
    border:0px solid blue;
    margin-left:10%;
    float:left;
    background-color: honeydew;
    border-radius:8px;
}
#div_fruit_list{
    width:100%;
    border:0px solid red;
}
#tbl_fruit{
    width:60%;
    line-height:28px;
    margin-top:16px;
    margin-left:20%;
}
#tbl_fruit , #tbl_fruit tr , #tbl_fruit th , #tbl_fruit td{
    border:1px solid gray;
    border-collapse:collapse;
    text-align:center;
    font-size:16px;
    font-family:"黑体";
    font-weight:lighter;

}
.w20{
    width:20%;
}
.delImg{
    width:24px;
    height:24px;
}
.btn{
    border:1px solid lightgray;
    width:80px;
    height:24px;
}

.center{
    text-align:center;
}
.f30{
    font-size: 30px;
}

index.css

*{
    color: threeddarkshadow;
}
a{
    text-decoration: none;
}
body{
    margin:0;
    padding:0;
    background-color:#808080;
}
div{
    position:relative;
    float:left;
}

#div_container{
    width:80%;
    height:100%;
    border:0px solid blue;
    margin-left:10%;
    float:left;
    background-color: honeydew;
    border-radius:8px;
}
#div_fruit_list{
    width:100%;
    border:0px solid red;
}
#tbl_fruit{
    width:60%;
    line-height:28px;
    margin-top:16px;
    margin-left:20%;
}
#tbl_fruit , #tbl_fruit tr , #tbl_fruit th , #tbl_fruit td{
    border:1px solid gray;
    border-collapse:collapse;
    text-align:center;
    font-size:16px;
    font-family:"黑体";
    font-weight:lighter;

}
.w20{
    width:20%;
}
.delImg{
    width:24px;
    height:24px;
}
.btn{
    border:1px solid lightgray;
    width:80px;
    height:24px;
}

.center{
    text-align:center;
}
.f30{
    font-size: 30px;
}

index.js

function delFruit(fid) {
    if(confirm('是否确认删除')){
        window.location.href='del.do?fid='+fid;
    }
    
}

function page(pageNo) {
    window.location.href="index?pageNo="+pageNo;

    
}

还有xml里对thymeleaf视图的配置

 
        view-prefix
        /
    
    
        view-suffix
        .html
    

视图的类

package com.xue.myssm.myspringmvc;

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;

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

        templateResolver.setPrefix(viewPrefix);

        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");

        templateResolver.setSuffix(viewSuffix);

        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);

        // ⑤设置是否缓存
        templateResolver.setCacheable(true);

        // ⑥设置服务器端编码方式
        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");

        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req, resp, getServletContext());

        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}

最后看看这简陋的成品

javaweb一阶段-表单的管理系统(sgg)_第4张图片

javaweb一阶段-表单的管理系统(sgg)_第5张图片

javaweb一阶段-表单的管理系统(sgg)_第6张图片

javaweb一阶段-表单的管理系统(sgg)_第7张图片

 虽然不堪入目,但是人是会进步的

你可能感兴趣的:(java,数据库,tomcat,mysql,后端)