You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无表单且直接运行JSP时从Servlet传递数据至JSP?

为啥直接跑JSP拿不到Servlet的数据?以及解决办法

嘿,我明白你现在的困惑——你在Servlet里查了数据库、把数据塞到request里,然后通过Dispatcher转发给JSP,这时候能拿到数据;但直接点开JSP或者输入JSP的URL,啥数据都没有,连JSTL都不管用。其实核心原因特别简单:直接运行JSP的时候,你的Servlet根本没被调用啊!

当你直接访问JSP的URL,服务器只会编译执行JSP本身,不会触发对应的Servlet逻辑——那Servlet里查的数据库数据、设置的request属性,自然不会出现在当前的请求里,JSP当然读不到。

那能不能实现“直接访问JSP就展示数据库数据”?当然可以!但得换个思路,让原本在Servlet里的逻辑,在JSP被访问时自动跑起来。下面给你几个靠谱的方案:

方案1:让JSP自动转发到Servlet(简单粗暴)

你可以在JSP的最顶部加一小段代码,让它先跳转到你的Servlet,等Servlet查完数据、塞好属性,再转发回这个JSP。这样用户直接访问JSP URL时,就会自动触发Servlet的逻辑。示例代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
    // 加个判断,避免无限循环——如果request里已经有数据,说明是Servlet转发过来的,直接渲染页面
    if (request.getAttribute("dbData") == null) {
        // 替换成你的Servlet的映射路径
        request.getRequestDispatcher("/your-servlet-mapping").forward(request, response);
        return; // 停止当前JSP的后续执行,不然会重复渲染
    }
%>
<!-- 下面是你的页面内容,用JSTL展示数据就行 -->
<c:forEach var="item" items="${dbData}">
    <div>${item.title}:${item.content}</div>
</c:forEach>

这个方案的好处是改动小,不需要额外写太多代码,但要注意Servlet的路径要写对,而且那个判断一定要加,不然会陷入无限转发的死循环。

方案2:用Filter拦截JSP请求(更规范的MVC做法)

如果想让代码更干净、符合MVC的分离原则,推荐写一个Filter(过滤器),拦截所有访问目标JSP的请求,在Filter里执行数据库查询、把数据塞到request里,再让请求继续走到JSP。这样数据加载的逻辑和页面完全分开,后期维护也方便。

示例Filter代码:

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;

@WebFilter(urlPatterns = "/your-target.jsp") // 拦截目标JSP的请求
public class DataLoadFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        // 这里调用你的数据库服务,获取数据
        List<YourDataModel> dbData = YourDatabaseService.getFromDB();
        // 把数据放到request属性里,JSP就能通过EL表达式拿到
        req.setAttribute("dbData", dbData);
        // 让请求继续往下走,到JSP页面
        chain.doFilter(request, response);
    }

    // init和destroy方法如果不需要可以留空或者简单实现
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void destroy() {}
}

配置好这个Filter之后,用户每次访问那个JSP,都会先经过Filter加载数据,再渲染页面,完美实现你的需求。

方案3:直接在JSP里写数据库逻辑(不推荐,但能用)

如果你实在不想碰Servlet或Filter,也可以直接在JSP里写Java代码调用数据库查询,但我真的不建议这么做——这会把业务逻辑和页面视图混在一起,代码难调试、难复用,页面也会变得臃肿不堪。不过还是给你个示例,你自己权衡:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.List" %>
<%@ page import="com.yourpackage.YourDataModel" %>
<%@ page import="com.yourpackage.YourDatabaseService" %>
<%
    // 直接在JSP里调用数据库服务
    List<YourDataModel> dbData = YourDatabaseService.getFromDB();
    request.setAttribute("dbData", dbData);
%>
<c:forEach var="item" items="${dbData}">
    <p>${item.name}</p>
</c:forEach>

最后再划个重点

直接跑JSP拿不到Servlet数据的本质就是:Servlet没执行,数据从来没被放进请求里。要实现直接访问JSP展示数据,核心就是让数据加载逻辑在JSP被访问时自动触发——优先推荐Filter的方案,其次是JSP转发的方式,尽量别用第三种把逻辑写在JSP里的做法。

内容的提问来源于stack exchange,提问作者arjunhitachi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:21:15