web前端 静态资源 访问不到 的处理办法

问题:对于一个简单的form表单,url究竟应该如何填写?

1、url的各部分组成

对于地址:http://192.168.1.1:8080/hello/index.html
其中:分解为三部分

  • 服务器地址: http://192.168.1.1:8080
  • WEB应用上下文: /hello
  • 网页或请求: /index.html

2、form表单中的action

HTML协议中要求,form的action属性,以“/”开头是绝对路径,不以“/”开头的是相对路径。

绝对路径是相对于服务器地址而言的。所以记住,很多时候一个斜杠就代表已经写了 http://192.168.1.1:8080这么多东西

相对路径是相对于当前网页或请求而言的。

根目录代表的是从最底层目录访问到当前目录,即绝对路径;

"./" 代表当前目录,"../"代表上级目录,"/"代表Web应用的根目录

  • 无“/”,代表是相对于web应用根目录,即http://localhost:8080/tomcat配置的虚拟目录/
  • 有“/”,代表是相对于web站点根目录,即http://localhost:8080/

3、具体写法:

例如:
Web Applicationcontexthello
http://localhost:8080/hello/index.html是欢迎页。

现在我的一个Controller的映射为@RequestMapping(“/fileUp”)
  如果页面的form中的action=“/fileUp,转向的URL为http://localhost:8080/fileUp,是无效的。
  以下是有效的写法,会转向“http://localhost:8080/hello/fileUp”:

  • action=“/hello/fileUp”
  • action=“./fileUp”
  • action=“fileUp” 无“/” 直接跳转到对于的资源名,这个也常见

4、RequestMapper(“/fileUp”) 这里的 / 可加可不加,但都是从上下文开始,而不是从服务器地址开始

web容器启动的时候,(org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping)会扫描Controller注解找到所有的Handler(这里把处理器就称为Handler,等会儿好理解)类,拿到所有的Handler类之后,会遍历这些Handler类,并且遍历这个Handler类中所有带RequestMapping的方法,同时把类和方法的路径拼起来(框架叫做combine,联结在一起,注意:Handler类可以不要RequestMapping),在这个过程中,会判断路径的最前面是否有斜线(/),如果没有,会拼一个斜线(/)

5、例子

重点理解下面的语句(针对action):

无“/”,代表是相对于web应用根目录,即http://localhost:8080/tomcat配置的虚拟目录/
有“/”,代表是相对于web站点根目录,即http://localhost:8080/
前端:

<form action="student/zhangsan/20" method="post">
    <input type="submit" value="注册学生">
</form>

 

后端:

复制代码
/**
* 创建资源 Post请求方式
* http://localhost:8080/myboot/student/zhangsan/20
*/
@PostMapping("/student/{name}/{age}")
public String createStudent(
    @PathVariable("name") String name,
    @PathVariable("age") Integer age){
    
    return "创建资源 student: name="+name+"#age="+age;
}
复制代码

以上内容转自:https://blog.csdn.net/YiGeiGiaoGiao/article/details/128750622

现在描述下我的问题:

  1.直接访问没问题:截图如下

访问地址:http://localhost:8080/spring_mvc/index.jsp

 

2.跳转就访问不到

访问地址:http://localhost:8080/spring_mvc/charpter07/logion

复制代码
@Controller
@RequestMapping("/charpter07")
public class Charpter07Controler {
    @GetMapping("/logion")
    public String logion(){
        System.out.println("跳转到logion.jsp");
        return "forward:/index.jsp";

    }
}
复制代码

 

 

 

 也就是说我们配置 

href="layui/css/layui.css"
src="layui/layui.js"
是相对路径。直接访问没问题,但是如果一旦经过了跳转,静态资源的访问路径就变成了
http://localhost:8080/spring_mvc/charpter07/layui/css/layui.css
http://localhost:8080/spring_mvc/charpter07/layui/layui.js
因此就会出现找不到的问题:
最终解决办法:通过添加绝对路径访问(如下图),这样,不管是直接访问,还是转发到此页面,访问路径就都是
http://localhost:8080/spring_mvc/layui/css/layui.css
http://localhost:8080/spring_mvc/layui/layui.js

 

此处给一个有意义的参考:https://www.cnblogs.com/jimisun/p/9418247.html

总结:一切找不到的问题,基本都是路径问题,要深入理解 路径(前端、后端)问题的本质 才能解决问题!

追加:

后来在springmvc中添加了拦截器,静态资源又访问不到了。

解决办法记录如下:

方式一:修改拦截器,放行静态资源:

复制代码
/**
 * @authour cyf
 * 2023/7/17 16:22
 * 登录拦截器
 */
public class CheckLogionInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String requestURI = request.getRequestURI();
        //此处判断需要放行的静态资源
        if(requestURI.endsWith(".js") || requestURI.endsWith(".css") || requestURI.endsWith(".js") ||
                requestURI.endsWith(".eot") || requestURI.endsWith(".svg") || requestURI.endsWith(".ttf") ||
                requestURI.endsWith(".woff") || requestURI.endsWith(".woff2")
        ){
            System.out.println("放行静态资源");
            return true;
        }

        HttpSession session = request.getSession();
        Object username = session.getAttribute("havaLogion");
        //如果没有登录重定向到 logion 页面
        if(!StringUtils.hasLength((String) username)){
            String contextPath = request.getContextPath();
            response.sendRedirect(contextPath+"/charpter07/logion");

            //会直接转发到post方法
            //request.getRequestDispatcher("/charpter07/logion").forward(request, response);
            return false;
        }
        return true;
    }
}
复制代码

方式二:在 web.xml 添加配置到最顶端,使用默认sevlet 进行静态资源处理

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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_3_1.xsd"
         version="3.1">

    <!--default servlet处理静态资源-->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.eot</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.svg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.ttf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.woff</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.woff2</url-pattern>
    </servlet-mapping>


    <!--配置springmvc-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--配置spring-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>

    <!--配置编码:如果配置了多个过滤器,那么字符编码过滤器一定要在最前面,否则失效-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <!--        <servlet-name>dispatcherServlet</servlet-name>-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--处理html 不支持 put delete-->
    <filter>
        <filter-name>hiddenFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenFilter</filter-name>
        <!--<servlet-name>dispatcherServlet</servlet-name>-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--过滤jsp 不处理put delete 的自定义过滤器,只能过滤 FORWARD-->
    <filter>
        <filter-name>restFilter</filter-name>
        <filter-class>com.mvc.filter.RestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>restFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <!--注意:只过滤转发-->
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

</web-app>
复制代码

方式三:在配置拦截器的springmvc的配置xml里,放行静态资源的文件夹,这需要吧所有静态资源放在一个文件夹里管理,否则,放行路径就得写很多了,配置如下:

推荐

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--设置springmvc 扫描路径-->
    <context:component-scan base-package="com.mvc.controler">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--默认视图解析器-配上前缀和后缀,简化逻辑视图名称  (视图模板?)-->
    <!-- org.springframework.web.servlet.DispatcherServlet 同一目录的 .properties 里   -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        <property name="prefix" value="/WEB-INF/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!--视图控制器 (立即访问) path:映射路径 view-name:访问名称 也会走 viewResolver
        注意:1.使用了这个标签后必须配置 <mvc:annotation-driven />  否则会造成所有的@Controller注解无法解析,导致404错误
            2.如果请求存在处理器,则这个标签对应的请求处理将不起作用。因为请求是先去找处理器处理,如果找不到才会去找这个标签配置
     -->
<!--    <mvc:view-controller path="/" view-name="main"></mvc:view-controller>-->
    <!-- 保证静态资源和动态请求都能够访问 -->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--访闻静态资源
        此配置表示 我们自己配置的请求由controller来处理,但是不能请求的处理交由tomcat来处理
        静态资源可以访问,但是动态请求无法访问
    -->
    <mvc:default-servlet-handler/>

    <!--    当配置了类型转换器,需要配置FormattingConversionServiceFactoryBean才能同时支持格式化和类型转换-->
    <mvc:annotation-driven conversion-service="conversionServiceName"></mvc:annotation-driven>
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="conversionServiceName">
        <property name="converters">
            <set>
                <bean class="com.mvc.converter.MyDateConverter" id="converter"></bean>
            </set>
        </property>
    </bean>

    <!--基于CommonsMultipartResolver 文件上传解析器-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <!--设置编码格式-->
        <property name="defaultEncoding" value="utf-8"></property>
        <!--文件上传最大字节数-->
        <property name="maxUploadSize" value="#{1024*1024}"></property>
    </bean>



    <!--配置拦截器-->
    <mvc:interceptors>
        <!--直接配置一个bean会拦截springmvc的所有请求-->
        <bean class="com.mvc.interceptor.MyInterceptor"></bean>
        <!-- 如果不是所有的请求都要拦截,可以加一个<mvc:interceptor>-->
        <mvc:interceptor>
            <!--需要拦截请求-->
            <mvc:mapping path="/**"/>
            <!--不需要拦截的请求 (只会拦截get请求)-->
            <mvc:exclude-mapping path="/charpter07/logion"/>
            <!--放行静态资源文件夹-->
            <mvc:exclude-mapping path="/static/**"/>
            <bean class="com.mvc.interceptor.CheckLogionInterceptor" id="logionInterceptor"></bean>
        </mvc:interceptor>

        <!--国际化三:配置拦截器进行 请求参数 ?locale=zh_CN 必须携带locale参数-->
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
    </mvc:interceptors>

    <!--设置国际化支持,配置国际化资源文件 id="messageSource“不能乱取名-->
    <bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
        <!--setBaseNames()-->
        <property name="basenames">
            <array>
                <value>i18n.logion</value>
            </array>
        </property>
    </bean>
    <!--    使用SessionLocaleResolver,保持local状态,会从session中获取local对象 id="localeResolver"只能叫localeResolver,为了覆盖springmvc默认AcceptHeaderLocaleResolver
         不配制的话默认使用的是 AcceptHeaderLocaleResolver,会从请求头里获取“Aceept-Language”
         国际化二:SessionLocaleResolver 替换默认的 AcceptHeaderLocaleResolver
    -->
    <bean class="org.springframework.web.servlet.i18n.SessionLocaleResolver" id="localeResolver"></bean>

</beans>
复制代码

本例将资源放在 static 文件夹下,供大家参考。当然你有多个过滤器,那么每个过滤器都需要对 static 文件夹进行放行处理,或者静态资源没有统一在一个文件夹里,那么拦截器里就要进行多个路径的放行了!

 

posted @   花开如梦  阅读(2285)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示