Tomcat & Servlet

Web相关概念回顾

软件架构

  1. C/S:客户端/服务器端
  2. B/S:浏览器/服务器端

资源分类

  1. 静态资源:所有用户访问后,得到的结果都是一样的,静态资源可以被浏览器直接解析,如:html、css、js

  2. 动态资源:每个用户访问相同资源后,得到的结果可能不一样。动态资源被访问后,需要先转换为静态资源,再返回给浏览器。

    如:servlet/jsp、php、asp…

网络通信三要素

  1. IP:计算机在网络上的唯一标识。

  2. 端口:应用程序在计算机中的唯一标识。0~65536

  3. 传输协议

    tcp:可靠传输协议

    udp:不可靠

web服务器软件

服务器:安装了服务器软件的计算机

服务器软件:接收用户的请求,处理请求,做出响应

web服务器软件:接收用用户的请求,处理请求,做出响应

  • 在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目
  • web容器

常见的web服务器软件

  • weblogic:oracle公司,大型JavaEE服务器,支持JavaEE规范,收费。
  • webSphere:IBM公司,大型JavaEE服务器,支持JavaEE规范,收费。
  • JBOSS:JBOSS公司,大型JavaEE服务器,支持JavaEE规范,收费。
  • Tomcat:Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范,免费。

JavaEE:Java语言在企业级开发中使用的技术规范和综合,一共规定了13项大的规范。

Tomcat

Tomcat配置

  1. 下载:https://tomcat.apache.org/download-80.cgi

  2. 安装:解压压缩包即可,注意:安装目录建议不要有中文

  3. 卸载:删除目录即可

  4. 启动:配置jdk环境变量,配置tomcat环境变量。然后cmd命令行直接startup启动tomcat服务器

    可能遇到的问题:

    黑窗口一闪而过:

    • 原因:没有正确配置JAVA_HOME环境变量
    • 解决方案:重新配置JAVA_HOME

    启动报错:

    • 暴力:找到占用的端口号,并且找到对应的进程,杀死该进程

      netstat -ano

    • 温柔:修改tomcat的端口号

      在配置文件conf/server.xml中修改

      <Connect prot=“xxxx”

  5. 关闭

    • 正常关闭:bin/shutdown.bat或者ctrl+c
    • 强制关闭:点击启动窗口的X
  6. 目录结构

    • bin:可执行文件
    • conf:配置文件
    • lib:依赖jar包
    • logs:日志文件
    • temp:临时文件
    • webapps:存放web项目
    • work:存放运行时数据

部署项目的方式

  1. 直接将项目放到webapps目录下即可

    /hello:项目的访问路径–>虚拟目录

    简化部署:将项目打成一个war包,再将war包放置到webapps目录下

    • war包会自动解压缩,删除项目时,只需要删除项目的war包即可,项目会自动删除。
  2. 配置conf/server.xml文件

    在<Host>标签体中配置

    <Context docBase=“E:\hello” path="/hehe" />

    • docBase:项目存放的路径
    • path:虚拟目录

    问题:不安全

  3. **推荐,**在conf/Catalina/localhost创建任意名称的xml文件。在文件中编写

    <Context docBase=“E:\hello” />

    虚拟目录:xml文件的名称

静态项目和动态项目

目录结构

Java动态项目的目录结构:

  • 项目的根目录

    • WEB-INF目录

      • web.xml:web项目的核心文件
      • classes目录:放置字节码文件的目录
      • lib目录:放依赖jar包

将Tomcat集成到IDEA中,并且创建JavaEE的项目,部署项目。

Servlet入门

概念

概念:运行在服务器端的小程序

  • Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
  • 以后我们自定义一个类,实现Servlet接口,复写方法

快速入门

  1. 创建JavaEE的项目

  2. 定义一个类,实现Servlet接口

    public class ServletDemo1 implements Servlet

  3. 实现接口中的抽象方法

  4. 配置Servlet

<!-- 配置Servlet -->
<servlet><servlet-name>demo1</servlet-name><servlet-class>cn.myz.web.servlet.Demo1</servlet-class>
</servlet><servlet-mapping><servlet-name>demo1</servlet-name><url-pattern>/demo1</url-pattern>
</servlet-mapping>

执行原理

  1. 当服务器接收到客户端浏览器的请求后,会解析这个请求的url路径,获取访问的Servlet的资源路径
  2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容,与请求资源路径一致。
  3. 如果有,则根据servlet-name找到对应的<servlet-class>的全类名。
  4. tomcat会将该类的字节码文件加载进内存,并创建其对象
  5. 调用其方法

Servlet生命周期

创建:执行init方法,只执行一次

  • Servlet什么时候被创建?

    默认情况下,第一次被访问时,Servlet被创建。但也可以去配置指定Servlet的创建时机。在servlet标签下配置

    • 第一次被访问时,创建:<load-on-startup>值为负数
    • 在服务器启动时,创建:<load-on-startup>值为0或正整数
  • Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的

    多个用户同时访问时,可能存在线程安全问题。

    解决方法:尽量不要在Servlet里定义成员变量。即使定义了成员变量也不要对其修改值。

提供服务:执行service方法,执行多次

  • 每次访问Servlet时,Service方法都会被调用一次

销毁:执行destroy方法,只执行一次

  • Servlet被销毁时执行。服务器关闭时,Servlet被销毁。
  • 注意:只有服务器正常关闭时,才会执行destroy方法。

Servlet3.0

优点

  • 支持注解配置。可以不需要web.xml

步骤

  1. 创建JavaEE项目,选择Servlet的版本3.0以上即可,可以不创建web.xml

  2. 定义一个类,实现Servlet接口

  3. 复写方法

  4. 在类上使用注解@WebServlet注解配置

    @WebServlet(“资源路径”)

java.lang.String[] value() default {};//代表urlPatterns()属性的配置
java.lang.String[] urlPatterns() default {};//相当于<url-pattern>
int loadOnStartup() default -1;//相当于<load-on-startup>javax.servlet.annotation.WebInitParam[] initParams() default {};boolean asyncSupported() default false;java.lang.String smallIcon() default "";java.lang.String largeIcon() default "";java.lang.String description() default "";java.lang.String displayName() default "";

IDEA与tomcat的相关配置

IDEA会为每一个tomcat部署的项目单独建立一个配置文件。

  • 配置文件路径可以通过查看控制台logCATALINA_BASE获得:Using CATALINA_BASE: “C:\Users\hp.IntelliJIdea2019.2\system\tomcat\Tomcat_8_5_70_20210827_servlet”

工作空间项目和tomcat部署的web项目

  • tomcat真正访问的是“tomcat部署的web项目”,“tomcat部署的web项目”对应着“工作空间项目”的web目录下的所有资源
  • WEB-INF目录下的资源不能被浏览器直接访问。
  • 断点调试

Servlet详解

Servlet体系结构

Servlet–接口

​ |

GenericServlet – 抽象类

​ |

HttpServlet --抽象类

GenericServlet

  • 将Servlet接口中其它方法做了默认空实现,只将service()方法作为抽象
  • 将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可

*HttpServlet

对http协议的一种封装,简化操作。使用步骤:

  1. 定义类继承HttpServlet
  2. 复写doGet/doPost方法

推荐使用继承HttpServlet复写doget/dopost方法

Servlet相关配置

urlpartten:Servlet访问路径

  • 一个Servlet可以定义多个访问路径:@WebServlet({“d1”,“dd1”,“ddd1”})
  • 路径定义规则:
    1. /xxx
    2. /xxx/xxx:多层路径,目录结构
    3. *.后缀名

HTTP

概念

概念:Hyper Text Transfer Protocol 超文本传输协议

传输协议:定义了客户端和服务器端通信时发送数据的格式。

特点:

  1. 基于TCP/IP的高级协议
  2. HTTP默认端口号:80
  3. 基于请求/响应模型:一次请求对应一次响应
  4. Http是一种无状态的协议:每次请求之间相互独立,不能交互数据

历史版本:

  • 1.0:每一次请求响应都会建立新的连接
  • 1.1:复用连接

请求消息数据格式

请求行

  • 请求方式 请求url 请求协议/版本

  • GET /login.html HTTP/1.1

  • 请求方式

    http协议有7种请求方式,常用的有2种

    GET:

    • 请求参数在请求行中,在url后。
    • 请求的url长度是有限制的。
    • 不安全

    POST:

    • 请求参数在请求体中。
    • 请求的url长度没有限制
    • 安全

请求头

  • 请求头名称:请求头值

  • 常见的请求头:

    User-Agent:浏览器告诉服务器,访问服务器使用的浏览器版本

    • 可以在服务器端获得不同浏览器的浏览器品牌和版本,返回给它们不同的代码,以解决不同的浏览器的兼容问题。

    Referer:http://localhost/login.html

    • 告诉服务器,当前请求从哪里来

    • 作用

      1.防盗链

      2.做统计工作

请求空行

  • 空行,就是用于分隔POST请求的请求头和请求体的。

请求体(正文)

  • 封装POST请求消息的请求参数的。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cache-Control: max-age=0
Connection: keep-alive
Host: localhost
If-Modified-Since: Sat, 28 Aug 2021 03:00:59 GMT
If-None-Match: W/“264-1630119659545”
sec-ch-ua: “Chromium”;v=“92”, " Not A;Brand";v=“99”, “Microsoft Edge”;v=“92”
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.78

Request

  1. tomcat服务器会根据请求url中的资源路径,创建对应的ServletDemo对象
  2. tomcat服务器,会创建request和response对象,request对象中封装请求消息数据。
  3. tomcat将request和response两个对象传递给service方法,并调用service方法。
  4. 程序员可以通过request对象获取请求消息数据,通过response对象设置响应消息数据
  5. 服务器在给浏览器做出响应之前,会从response对象中拿程序员设置的响应消息数据。

Request对象和response对象的原理

  1. request和response对象是由服务器创建,我们来使用它们。
  2. request对象是来获取请求信息,response对象是来设置响应信息

继承体系结构

request对象继承体系结构

ServletRequest --接口

​ |继承

HttpServletRequest --接口

​ |实现

org.apache.catalina.connector.RequestFacade类

Request功能

获取请求消息数据

获取请求行数据

  • GET /day14/demo1?name=zhangsan HTTP/1.1

  • 方法

    1. 获取请求方式:GET

      String getMethod()

    2. (*)获取虚拟目录:/day14

      String getContextPath()

    3. 获取Servlet路径:/demo1

      String getServletPath()

    4. 获取get方式请求参数:name=zhangsan

      String getQueryString()

    5. (*)获取请求URI:

      String getRequestURI() /day14/demo1

      StringBuffer getRequestURL() http://localhost/day14/demo1

      URL:统一资源定位符,http://localhost/day14/demo1

      URI:统一资源标识符,/day14/demo1

    6. 获取协议及版本:HTTP/1.1

      String getProtocol()

    7. 获取客户机的IP地址:

      String getRemoteAddr()

获取请求头数据

  • 方法
  1. (*)String getHeader(String name):通过请求头的名称获取请求头的值
  2. Enumeration<String> getHeaderNames():获取所有的请求头名称

获取请求体数据

  • 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数

  • 步骤

    1. 获取流对象

      BufferedReader getReader():获取字符输入流,只能操作字符数据

      ServletInputStream getInputStream():获取字节输入流,可以操作所有类型的数据

      • 在文件上传知识点后详解
    2. 再从流对象中拿数据

其它功能

获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数

  1. String getParameter(String name):根据参数名称获取参数值 username=zs&password=123

  2. String[] getParemeterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game

  3. Enumeration<String> getParameterName():获取所有请求的参数名称

  4. Map<String,String[]> getParameterMap():获取所有参数的map集合

  • 中文乱码问题:

    • get方式:tomcat8已经将get方式乱码entity解决了

    • post方式:会乱码

      解决方法:在获取参数前,设置request的编码request.setCharacterEncoding(“utf-8”);

    package request;import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.util.Enumeration;
    import java.util.Map;
    import java.util.Set;/*** @author: 小码农* @create: 2021-08-28 21:36**/
    @WebServlet("/RequestDemo6")
    public class RequestDemo6 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// post 获取请求参数// 根据参数名获取参数值String username = req.getParameter("username");/*System.out.println("post");System.out.println(username);*/// 根据参数名称获取参数值的数组/*String[] hobbies = req.getParameterValues("hobby");for (String hobby:hobbies){System.out.println(hobby);}*/// 获取所有请求的参数名称/*Enumeration<String> parameterNames = req.getParameterNames();while (parameterNames.hasMoreElements()){String name = parameterNames.nextElement();System.out.println(name);String parameter = req.getParameter(name);System.out.println(parameter);System.out.println("---------------");}*/// 获取所有参数的map集合Map<String, String[]> parameterMap = req.getParameterMap();// 遍历Set<String> strings = parameterMap.keySet();for (String name:strings){// 根据键获取值String[] strings1 = parameterMap.get(name);System.out.println(name);for (String value:strings1){System.out.println(value);}System.out.println("----------------");}}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// get 获取请求参数// 根据参数名获取参数值/*String username = req.getParameter("username");System.out.println("get");System.out.println(username);*/this.doPost(req,resp);}
    }
    

请求转发:一种在服务器内部的资源跳转方式

  • 步骤:
  1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
  2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
  • 特点
  1. 浏览器地址栏路径不发生变化
  2. 转发只能转发到当前服务器内部资源中。
  3. 转发是一次请求
package request;import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author: 小码农* @create: 2021-08-28 21:36**/
@WebServlet("/RequestDemo8")
public class RequestDemo8 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("demo8888被访问了...");// 存储数据到request域中req.setAttribute("msg","hello");// 转发到demo9资源req.getRequestDispatcher("/RequestDemo9").forward(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}
}
package request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author: 小码农* @create: 2021-08-28 21:36**/
@WebServlet("/RequestDemo9")
public class RequestDemo9 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取数据Object msg = req.getAttribute("msg");System.out.println(msg);System.out.println("demo9999被访问了...");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}
}

共享数据

域对象:一个有作用范围的对象,可以在范围内共享对象

request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据。

方法:

  1. setAttribute(String name,Object obj):存储数据
  2. Object getAttribute(String name):通过键获取值
  3. void removeAttribute(String name):通过键移除键值对

获取ServletContext

  • ServletContext getServletContext()

案例:用户登录

需求:

  1. 编写login.html登录页面

    username&password 两个输入框

  2. 使用Druid数据库连接池技术,操作mysql,day14数据库中的user表

  3. 使用jdbcTemplate技术封装JDBC

  4. 登录成功跳转到SuccessServlet展示:登陆成功!用户名,欢迎您

  5. 登陆失败挑战到FailServlet展示:登录失败,用户名或密码错误

开发步骤

  1. 创建项目,导入html页面,配置文件,导入jar包

    driverClassName=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/db2
    username=root
    password=123456
    # 初识化连接
    initialSize=5
    # 最大连接数
    maxActive=10
    # 超时时间
    maxWait=3000
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hM3fZiAk-1630236204261)(image/image-20210829163357548.png)]

  2. 创建数据库环境

    // 创建LOGIN数据库
    CREATE DATABASE LOGIN;
    USE LOGIN;
    // 创建USER表
    CREATE TABLE USER(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(32) UNIQUE NOT NULL,
    password VARCHAR(32) NOT NULL
    );
    
  3. 创建com.myz.domain,创建User实体类

    package com.myz.domain;/*** @author: 小码农* @create: 2021-08-29 16:35* 用户实体类**/
    public class User {private int id;private String username;private String password;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
    }
    
  4. 创建包com.myz.dao,创建类UserDao,提供login方法

    创建JDBC工厂类

    package com.myz.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;/** * @author: 小码农 * @create: 2021-08-29 16:40 * JDBC工具类,使用Durid连接池 **/public class JDBCUtils {    private static DataSource ds;    static {        // 1.加载配置文件        Properties pro = new Properties();        // 2.使用ClassLoader加载配置文件,获取字节输入流        InputStream resourceAsStream = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");        try {            pro.load(resourceAsStream);            // 3.初始化连接池对象            ds = DruidDataSourceFactory.createDataSource(pro);        } catch (IOException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }    }    /*    * 获取连接池对象    * */    public static DataSource getDataSource(){        return ds;    }    /*    * 获取连接Connection对象    * */    public static Connection getConnection() throws SQLException {        return ds.getConnection();    }}
    

    UserDao类

    package com.myz.dao;import com.alibaba.druid.util.JdbcUtils;
    import com.myz.domain.User;
    import com.myz.utils.JDBCUtils;
    import org.springframework.dao.DataAccessException;
    import org.springframework.jdbc.core.BeanPropertyRowMapper;
    import org.springframework.jdbc.core.JdbcTemplate;/*** @author: 小码农* @create: 2021-08-29 16:37* 操作数据库中user表的类**/
    public class UserDao {//声明JDBCTemplate对象共用private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());/** 登录方法* loginUser只有用户名密码* user包含用户全部数据** */public User login(User loginUser){try {// 1.编写sqlString sql = "select * from user where username=? and password=?";// 2.调用query方法User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), loginUser.getUsername(), loginUser.getPassword());return user;}catch (DataAccessException e){e.printStackTrace();return null;}}
    }
    
  5. 编写com.myz.servlet.LoginServlet类

  6. login.html中的form表单的action路径写法

    • 虚拟目录+Servlet的资源路径
  7. BeanUtils工具类,简化数据封装

    • 用于封装JavaBean的
    1. JavaBean:标准的Java类

      要求

      1. 类必须被public修饰

      2. 必须提供空参的构造器

      3. 成员变量必须使用private修饰

      4. 提供公共setter和getter方法

      功能:封装数据

    2. 概念:

      成员变量

      属性:setter和getter方法截取后的产物

      ​ 例如:getUsername() --> Username ——>username

    3. 方法:

      1. setProperty(Object obj,String name,String value):把value值按照obj对象有关于name的set方法,对obj赋值
      2. getProperty(Object obj,String name):根据name调用obj对象的getname方法,返回value值。
      3. populate(Object obj,Map map):封装JavaBean,它会把map集合的键值对信息,封装到对应的JavaBean对象中。

Tomcat Servlet Request相关推荐

  1. Tomcat servlet工作原理

    Java web 的基础就是servlet,其也是Java web的根. Tomcat 的容器等级中,Context 容器是直接管理 Servlet 在容器中的包装类 Wrapper,所以 Conte ...

  2. SpringBoot实战(十一):MultipartException: Could not parse multipart servlet request

    强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan [前言] 有个在线上跑了一段时间的上传文件的程序报错,查了些资料,最终通过设置上传文件的临时路径 ...

  3. Tomcat Servlet 工作原理

    文章目录 Tomcat Servlet 工作原理 Servlet Tomcat解析Context容器过程及如何构建Servlet Servlet容器启动过程 Web应用初始化工作 创建Servlet实 ...

  4. 解决:org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request;

    项目场景: 微服务修改保存,出现系统异常 问题描述 报错日志如下: | 2022-10-24 11:32:42.882 |-[1;31mERROR[m [http-nio-9000-exec-4] [ ...

  5. Intellij IDEA 2020.2.3 配置使用 tomcat+servlet

    Intellij IDEA 2020.2.3 配置使用 tomcat+servlet 创建项目 配置tomcat服务器 初步使用 执行jsp文件 执行servlet tomcat版本问题 手动导入se ...

  6. 一、Web服务器——Tomcat Servlet学习笔记

    今日内容 web相关概念回顾 web服务器软件:Tomcat Servlet入门学习 一.web相关概念回顾 软件架构 C/S:客户端/服务器端 B/S:浏览器/服务器端 资源分类 静态资源:所有用户 ...

  7. servlet request参数只能取一次解决方法

    servlet request参数只能取一次解决方法 参考文章: (1)servlet request参数只能取一次解决方法 (2)https://www.cnblogs.com/go4mi/p/10 ...

  8. 张利国java pdf_Java Web开发与实战–Eclipse+Tomcat+Servlet+JSP整合应用 (刘伟张利国) PDF...

    资源名称:Java Web开发与实战–Eclipse+Tomcat+Servlet+JSP整合应用 (刘伟,张利国) PDF 第1章 web开发工具的安装与使用 第2章 web编程技术基础 第3章 s ...

  9. JavaWeb+Tomcat+Servlet使用<c:foreach>标签时,jsp等网页文件获取不到request域中的数据

    自己也是刚学习就遇到了这个问题,上网找了两天,弄清楚了就分享出来 我的各个文件都没有报错,而且 jdk 和 jstl 的版本,web.xml 的版本都没什么问题,而且也能获取数据库中的数据,但是使用 ...

最新文章

  1. 十年学术生涯新开端:港中文助理教授周博磊宣布加入UCLA
  2. 很专业的Flash游戏
  3. Leetcode 相关资料
  4. 2021-11-28
  5. 不会玩电脑怎么学计算机,不会玩电脑怎么学
  6. 微信5.0登录提示服务器繁忙,iOS集成友盟社会化分享微信无法登录?
  7. jdbc建立数据库连接的helloword
  8. 如何制作扫描版的文档
  9. 为什么阿里强制 boolean 类型变量不能使用 is 开头
  10. HenCoder Android 开发进阶:自定义 View 1-4 Canvas 对绘制的辅助 clipXXX() 和 Matrix
  11. 笔记本相机测试软件,联想笔记本人脸识别软件(Lenovo VeriFace)
  12. mysql blast2go,blast2go
  13. 什么相片可以两张弄成一张_美图秀秀怎么把两张图片合成一张?美图秀秀两张图片融合方法汇总_图形图像_软件教程_脚本之家...
  14. Themeforest上销量第一的WordPress高级企业主题
  15. java后台实现HTTPS协议方法
  16. mysql的right函数_MySQL数据库中系统函数right功能简介
  17. 在制品与前置时间(又叫交付时间)
  18. unity helios_用于Eclipse Helios的JBoss工具!
  19. IT运维大咖带你玩转企业信息运维自动化
  20. linux下组播遇到的问题及解决办法

热门文章

  1. hiho一下 第139周 买零食
  2. VMS(VELO) tips[转载]
  3. goldenboy机器人_急求阿西莫夫机器人,基地,帝国三大系列的书名及其简介
  4. 品优购商城项目常见BUG解析
  5. 会声会影 2020 23.2.0.587 旗舰版
  6. 电化学气体传感器的工作原理
  7. Cocos2dx 3.1.1 之 加速传感器、监听物理按键
  8. ArcGIS 对地下管线进行分类标注
  9. 冰与火之歌-五王之战(优达数据分析进阶项目)
  10. 2020.9.9华为笔试记忆:KMP+记忆化搜索+字典树