Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
Web(用户)首先请求http页面,web服务器对其响应显示页面;
用户点击表单提交按钮,调用(request)服务器端的add(表单中定义的action),add调用java类;
java类中包括获取用户发送的数据操作、调用DAO中的方法添加到数据库、控制台打印。
下面使用idea2022企业版+mysql8。
下面以以下表格为题示例。
- CREATE TABLE 't_fruit' (
- 'fid' INT(11) NOT NULL AUTO_INCREMENT,
- 'fname' VARCHAR(20) NOT NULL,
- 'price' INT(11) DEFAULT NULL,
- 'fcount' INT(11) DEFAULT NULL,
- 'remark' VARCHAR(50) DEFAULT NULL,
- PRIMARY KEY ('fid')
- ) ENGINE=INNODB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;
创建lib文件,将驱动文件复制进去并将文件添加为库。
使用DAO对数据库操作。
文件结构:
其中,URL 3306/ 后面为数据库名字;
USER 为用户名;
PWD为密码;
注意修改!
- package com.fruit.dao.base;
- 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.jdbc.Driver" ;
- public final String URL = "jdbc:mysql://localhost:3306/javaweb?useUnicode=true&characterEncoding=utf-8&useSSL=false";
- public final String USER = "root";
- public final String PWD = "ad" ;
-
- 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() ;
-
- 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
- Object columnValue = rs.getObject(i+1); //33 苹果 5
- columnValueArr[i]=columnValue;
- }
- return columnValueArr ;
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- close(rs,psmt,conn);
- }
- return null ;
- }
-
- //执行查询,返回单个实体对象
- protected T load(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();
- //6.解析rs
- if(rs.next()){
- T entity = (T)entityClass.newInstance();
-
- for(int i = 0 ; i
- String columnName = rsmd.getColumnName(i+1); //fid fname price
- Object columnValue = rs.getObject(i+1); //33 苹果 5
- setValue(entity,columnName,columnValue);
- }
- return entity ;
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } finally {
- close(rs,psmt,conn);
- }
- return null ;
- }
-
-
- //执行查询,返回List
- protected List
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
- String columnName = rsmd.getColumnName(i+1); //fid fname price
- Object columnValue = rs.getObject(i+1); //33 苹果 5
- setValue(entity,columnName,columnValue);
- }
- list.add(entity);
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } finally {
- close(rs,psmt,conn);
- }
- return list ;
- }
- }
FruitDAOImpl类
- package com.fruit.dao.impl;
- import com.fruit.dao.FruitDAO;
- import com.fruit.dao.base.BaseDAO;
- import com.fruit.pojo.Fruit;
-
- import java.util.List;
-
- public class FruitDAOImpl extends BaseDAO<Fruit> implements FruitDAO {
- @Override
- public List<Fruit> getFruitList() {
- return super.executeQuery("select * from t_fruit");
- }
-
- @Override
- public boolean addFruit(Fruit fruit) {
- String sql = "insert into t_fruit values(0,?,?,?,?)";
- int count = super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark()) ;
- //insert语句返回的是自增列的值,而不是影响行数
- //System.out.println(count);
- return count>0;
- }
-
- @Override
- public boolean updateFruit(Fruit fruit) {
- String sql = "update t_fruit set fcount = ? where fid = ? " ;
- return super.executeUpdate(sql,fruit.getFcount(),fruit.getFid())>0;
- }
-
- @Override
- public Fruit getFruitByFname(String fname) {
- return super.load("select * from t_fruit where fname like ? ",fname);
- }
-
- @Override
- public boolean delFruit(String fname) {
- String sql = "delete from t_fruit where fname like ? " ;
- return super.executeUpdate(sql,fname)>0;
- }
- }
FruitDAO抽象类
- import com.fruit.pojo.Fruit;
- import java.util.List;
- public interface FruitDAO {
- //查询库存列表
- List
getFruitList(); -
- //新增库存
- boolean addFruit(Fruit fruit);
-
- //修改库存
- boolean updateFruit(Fruit fruit);
-
- //根据名称查询特定库存
- Fruit getFruitByFname(String fname);
-
- //删除特定库存记录
- boolean delFruit(String fname);
- }
Fruit类
- package com.fruit.pojo;
- 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 ;
- }
- }
三、使用TomCat新建项目
见前一文章。
四、Servlet获取参数
web文件结构
hello.html文件
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Titletitle>
- head>
- <body>
- <form action="add" method="post">
- 名称:<input type="text" name="fname"/><br/>
- 价格:<input type="text" name="price"/><br/>
- 库存:<input type="text" name="fcount"/><br/>
- 备注:<input type="text" name="remark"/><br/>
- <input type="submit" value="添加"/>
- form>
- body>
- html>
web.xml文件
此文件用于通过html中表单的action找到对应的类。
此文件执行步骤:
1、用户发请求,(action=add)
2、项目中,web.xml中找到url-pattern = /add
3、找servlet-name=com.fruit.servlets.AddServlet
4、找和servlet-mapping中servlet-name一致的servlet
5、找servlet-class
6、用户发送的是post请求,tomcat会执行AddServlet中的doPost方法
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
- version="4.0">
- <servlet>
- <servlet-name>AddServletservlet-name>
- <servlet-class>com.servlets.AddServletservlet-class>
- servlet>
- <servlet-mapping>
- <servlet-name>AddServletservlet-name>
- <url-pattern>/addurl-pattern>
- servlet-mapping>
-
- web-app>
AddServlet类
此类分为两部分:接收客户端数据和向数据库发送数据。
可能存在HttpServlet不存在问题,往下看。
- package com.servlets;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import com.fruit.dao.FruitDAO;
- import com.fruit.dao.impl.FruitDAOImpl;
- import com.fruit.pojo.Fruit;
-
- public class AddServlet extends HttpServlet {
- @Override
- /**接收客户端发送数据*/
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- request.setCharacterEncoding("utf-8");//解决输入中文乱码问题
- String fname = request.getParameter("fname");
- String priceStr = request.getParameter("price");
- Integer price = Integer.parseInt(priceStr);
- String fcountStr = request.getParameter("fcount");
- Integer fcount = Integer.parseInt(fcountStr);
- String remark = request.getParameter("remark");
-
- /**向数据库发送数据*/
- FruitDAO fruitDAO = new FruitDAOImpl();
- boolean flag = fruitDAO.addFruit(new Fruit(0,fname,price,fcount,remark));
- System.out.println(flag ? "添加成功":"添加失败");
- }
- }
HttpServlet不存在解决:
选择库中的Tomcat并确定。
此时,外部库中有了servlet-api
其他问题:
打开项目结构,查看是否还有问题,如有直接修复
五、测试
输入信息,点击添加,数据库中出现数据信息,表示成功。
-
相关阅读:
SpringBoot和SpringCloud的区别,使用微服务的好处和缺点
发明专利快速预审多久出结果?
1.13.C++项目:仿muduo库实现并发服务器之TcpServer模块的设计
中缀表达式转后缀表达式详细思路及代码实现
自定义类型:结构体(内存对齐),枚举,联合
解决chrome extension popup最大宽高限制(800x600)
JavaOOP-类、对象、方法、变量作用域及JavaDoc注释
day04_java基础
【SpringCloud-学习笔记】Nacos配置管理
什么是副业思维,副业应该怎么做,用创业思维分析副业的可行性
-
原文地址:https://blog.csdn.net/Tir_zhang/article/details/126101192