Spring mvc не может отображать ресурсы (например, html) без ограничений [duplicate]

Большинство ответов здесь затрагивают этот вопрос в очень сухих технических терминах. Я хотел бы остановиться на этом в терминах, которые могут понять обычные люди.

Представьте, что вы пытаетесь нарезать пиццу. У вас есть роботизированный резак для пиццы, который может разрезать кусочки пиццы ровно пополам. Он может вдвое сократить целую пиццу, или он может сократить вдвое существующий кусочек, но в любом случае половина всегда точна.

У этого резца пиццы очень хорошие движения, и если вы начнете с целой пиццы, затем уменьшите вдвое и продолжайте вдвое уменьшать наименьший срез каждый раз, вы можете сделать половину 53 раза , прежде чем срез слишком мал для даже его высокоточных способностей. В этот момент вы уже не можете вдвое уменьшить этот тонкий срез, но должны либо включать, либо исключать его, как есть.

Теперь, как бы вы отделили все срезы таким образом, чтобы добавить один (0,1) или одну пятую (0,2) пиццы? На самом деле подумайте об этом и попробуйте разобраться. Вы даже можете попытаться использовать настоящую пиццу, если у вас есть мифическая пресса для резки пиццы под рукой. : -)


Большинство опытных программистов, конечно же, знают реальный ответ, который заключается в том, что нет возможности собрать кусок точной десятой или пятой пиццы используя эти срезы, независимо от того, насколько мелко вы их нарезаете. Вы можете сделать довольно хорошее приближение, и если вы добавите аппроксимацию 0,1 с аппроксимацией 0,2, вы получите довольно хорошее приближение 0,3, но это все равно именно это, приближение.

Для двойного -оценки (это точность, которая позволяет вам вдвое сократить вашу пиццу 53 раза), цифры сразу меньше и больше 0,1 - 0.09999999999999999167332731531132594682276248931884765625 и 0,1000000000000000055511151231257827021181583404541015625. Последнее немного ближе к 0,1, чем первое, поэтому числовой синтаксический анализатор, учитывая ввод 0,1, благоприятствует последнему.

(Разница между этими двумя числами - это «самый маленький срез», который мы должны решить либо включить, что вводит восходящее смещение, либо исключить, что приводит к смещению вниз. Техническим термином для этого наименьшего среза является ulp .)

В случай 0,2, числа все одинаковы, просто увеличиваются в 2 раза. Опять же, мы одобряем значение, которое немного выше 0,2.

Обратите внимание, что в обоих случаях приближения для 0,1 и 0.2 имеют небольшое смещение вверх. Если мы добавим достаточно этих предубеждений, они будут толкать число дальше и дальше от того, что мы хотим, а на самом деле, в случае 0,1 + 0,2, смещение достаточно велико, чтобы получившееся число больше не было самым близким числом до 0,3.

в частности, 0,1 + 0,2 действительно 0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 = 0.3000000000000000444089209850062616169452667236328125, тогда как число ближе к 0,3 фактически 0,299999999999999988897769753748434595763683319091796875.

П.С. Некоторые языки программирования также предоставляют резаки для пиццы, которые могут разделять фрагменты на точные десятки . Хотя такие резаки для пиццы необычны, если у вас есть доступ к одному, вы должны использовать его, когда важно получить ровно одну десятую или одну пятую части среза.

( Первоначально опубликовано на Quora.)

ч>

188
задан user2418306 2 May 2016 в 20:12
поделиться

21 ответ

Поскольку я потратил много времени на эту проблему, я решил поделиться своим решением. Начиная с весны 3.0.4, есть параметр конфигурации, который называется <mvc:resources/> (подробнее об этом на веб-сайте справочной документации ), который может использоваться для обслуживания статических ресурсов, при этом все еще используется DispatchServlet на вашем сайте. root.

Чтобы использовать это, используйте структуру каталогов, которая выглядит следующим образом:

src/
 springmvc/
  web/
   MyController.java
WebContent/
  resources/
   img/
    image.jpg
  WEB-INF/
    jsp/
      index.jsp
    web.xml
    springmvc-servlet.xml

Содержимое файлов должно выглядеть так:

src / springmvc / web / HelloWorldController.java:

package springmvc.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloWorldController {

 @RequestMapping(value="/")
 public String index() {
  return "index";
 }
}

WebContent / WEB-INF / web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <servlet>
  <servlet-name>springmvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>
</web-app>

WebContent / WEB-INF / springmvc-servlet .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-2.5.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- not strictly necessary for this example, but still useful, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-controller for more information -->
 <context:component-scan base-package="springmvc.web" />

    <!-- the mvc resources tag does the magic -->
 <mvc:resources mapping="/resources/**" location="/resources/" />

    <!-- also add the following beans to get rid of some exceptions -->
 <bean      class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
 <bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
 </bean>

    <!-- JSTL resolver -->
 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass"
   value="org.springframework.web.servlet.view.JstlView" />
  <property name="prefix" value="/WEB-INF/jsp/" />
  <property name="suffix" value=".jsp" />
 </bean>

</beans>

WebContent / jsp / index.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<h1>Page with image</h1>
<!-- use c:url to get the correct absolute path -->
<img src="<c:url value="/resources/img/image.jpg" />" />

Надеюсь, что это поможет: -)

257
ответ дан Joris 1 September 2018 в 09:48
поделиться

Я знаю, что есть несколько конфигураций для использования статического содержимого, но мое решение заключается в том, что я просто создаю большую папку веб-приложений в вашем tomcat. Этот «bulk webapp» обслуживает только статическое содержимое без обслуживания приложений. Это безболезненное и простое решение для обслуживания статического содержимого для вашего фактического весеннего webapp.

Например, я использую две папки webapp на моем tomcat.

  1. springapp : он запускает только весеннее веб-приложение без статического содержимого, такого как imgs, js или css. [посвященный для весенних приложений.)
  2. Ресурсы
  3. : он обслуживает только статическое содержимое без JSP, сервлета или любого вида веб-приложения java. (посвященный статическому содержимому)

Если я хочу использовать javascript, я просто добавляю URI для своего javascript-файла.

EX> / resources / path / to / js / myjavascript.js

Для статических изображений я использую тот же метод.

EX> / resources / path / to /img/myimg.jpg

Наконец, я поставил «ограничение безопасности» на моем tomcat, чтобы заблокировать доступ к фактическому каталогу. Я помещал «никто» в список ограничений, чтобы страница генерировала «запрещенную ошибку 403», когда люди пытались получить доступ к пути статического содержимого.

Пока это работает очень хорошо для меня. Я также заметил, что многие популярные сайты, такие как Amazon, Twitter и Facebook, используют разные URI для обслуживания статического содержимого. Чтобы узнать это, просто щелкните правой кнопкой мыши на любом статическом содержимом и проверьте их URI.

1
ответ дан 0DayHack 1 September 2018 в 09:48
поделиться

Проблема связана с URLPattern

Измените свой шаблон URL на вашем сервлет-сопоставлении с "/" на "/ *"

0
ответ дан asif malek 1 September 2018 в 09:48
поделиться

В Spring 3.0.x добавьте следующее в ваш servlet-config.xml (файл, который настроен в web.xml как contextConfigLocation. Вам также нужно добавить пространство имен mvc, но просто Google для этого, t знает как!;)

Это работает для меня

<mvc:default-servlet-handler/>

С уважением

Аюб Малик

38
ответ дан Ayub Malik 1 September 2018 в 09:48
поделиться

С весны 3 все ресурсы должны отображаться по-другому. Вы должны использовать тег, чтобы указать расположение ресурсов.

Пример:

<mvc:resources mapping="/resources/**" location="/resources/" />

Таким образом вы направляете сервлет диспетчера для поиска ресурсов каталога для поиска статического содержимого.

2
ответ дан Balasubramanian Jayaraman 1 September 2018 в 09:48
поделиться

Я решил это так:

<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.gif</url-pattern>
</servlet-mapping>
<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>

Это работает на Tomcat и, конечно же, Jboss. Однако в конце концов я решил использовать решение Spring предоставляет (как уже упоминалось, rozky), который гораздо более портативен.

2
ответ дан Chepech 1 September 2018 в 09:48
поделиться

Это может быть достигнуто, по крайней мере, тремя способами.

Решения:

  • выставляют html в качестве файла ресурсов
  • , инструктируют JspServlet для также обрабатывать * .html-запросы
  • пишите свой собственный сервлет (или переходите к другим существующим запросам сервлетов в * .html).

Для получения полного примера кода, как достичь этого пожалуйста, ответьте на мой ответ в другом сообщении: Как сопоставить запросы к HTML-файлу в Spring MVC?

15
ответ дан Community 1 September 2018 в 09:48
поделиться

Я нашел способ обойти это с помощью urlrewritefilter от tuckey.

В web.xml:

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  <servlet>
    <servlet-name>app</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>app</servlet-name>
    <url-pattern>/app/*</url-pattern>
  </servlet-mapping>

В urlrewrite.xml:

<urlrewrite default-match-type="wildcard">
<rule>
    <from>/</from>
    <to>/app/</to>
</rule>
<rule match-type="regex">
    <from>^([^\.]+)$</from>
    <to>/app/$1</to>
</rule>
<outbound-rule>
    <from>/app/**</from>
    <to>/$1</to>
</outbound-rule>    

Это означает, что любой uri с символом '.' в нем (например, style.css) не будет переписано.

11
ответ дан hamo 1 September 2018 в 09:48
поделиться
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:default-servlet-handler/>
</beans>

, и если вы хотите использовать настройку на основе аннотаций, используйте код

@Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
0
ответ дан Jekin Kalariya 1 September 2018 в 09:48
поделиться

Это сделало реальную работу в моем случае

в web.xml:

...
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/images/*</url-pattern>
    <url-pattern>/css/*</url-pattern>
    <url-pattern>/javascripts/*</url-pattern>
</servlet-mapping>


<servlet-mapping>
    <servlet-name>spring-mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

...

1
ответ дан Jorge Sanchez 1 September 2018 в 09:48
поделиться

У меня такая же проблема, и я нашел ответ Йориса очень полезным. Но дополнительно мне нужно добавить

<mvc:annotation-driven /> 

в файл конфигурации сервлета. Без этого сопоставление ресурсов не будет работать, и все обработчики перестанут работать. Надеюсь, это поможет кому-то.

5
ответ дан Lucky 1 September 2018 в 09:48
поделиться

После того, как вы столкнулись с одним и тем же процессом принятия решений, описанным здесь, я решил пойти с предложением ResourceServlet, которое работает довольно хорошо.

Обратите внимание, что вы получаете больше информации о том, как использовать веб-поток в своем maven build здесь: http://static.springsource.org/spring-webflow/docs/2.0.x/reference/html/ch01s05.html

Если вы используете стандартным центральным хранилищем Maven является артефакт (в противоположность вышеупомянутому расслоенному источнику):

<dependency>
    <groupId>org.springframework.webflow</groupId>
    <artifactId>spring-js</artifactId>
    <version>2.0.9.RELEASE</version>
</dependency> 
0
ответ дан ngeek 1 September 2018 в 09:48
поделиться

Я только что справился с этой проблемой в Spring MVC 3.0, и я сначала пошел с параметром UrlRewriteFilter. Однако я не был доволен этим решением, поскольку он «не чувствовал себя хорошо» (я не единственный), см. Ссылку выше на Форумы Spring, где слово «взломать» появляется несколько раз).

Итак, я придумал аналогичное решение для «Неизвестного (Google)», но заимствовал идею наличия всего статического контента из / static / (взятого из версии Spring Roo приложения Pet Store). Сервлет «по умолчанию» не работал для меня, но SpringSourceLash Spring Spring (также был взят из созданного Spring Spring созданного приложения).

Web.xml:

<servlet>
    <servlet-name>mainDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet>
    <servlet-name>Resource Servlet</servlet-name>
    <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>mainDispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>Resource Servlet</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

Единственное изменение Я сделал JSP, чтобы добавить / static / путь к URL-адресам для CSS, JS и изображений. Например. "$ {pageContext.request.contextPath} /static/css/screen.css".

для пользователей Maven зависимость для "org.springframework.js.resource.ResourceServlet":

<dependency>
    <groupId>org.springframework.webflow</groupId>
    <artifactId>org.springframework.js</artifactId>
    <version>2.0.8.RELEASE</version>
</dependency>
12
ответ дан nickdos 1 September 2018 в 09:48
поделиться

Я просто добавлю три правила до правила весны по умолчанию (/ **) к urlrewritefilterу tuckey (urlrewrite.xml), чтобы решить проблему

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN" "http://tuckey.org/res/dtds/urlrewrite3.0.dtd">
    <urlrewrite default-match-type="wildcard">
     <rule>
      <from>/</from>
      <to>/app/welcome</to>
     </rule>
     <rule>
      <from>/scripts/**</from>
      <to>/scripts/$1</to>
     </rule>
     <rule>
      <from>/styles/**</from>
      <to>/styles/$1</to>
     </rule>
     <rule>
      <from>/images/**</from>
      <to>/images/$1</to>
     </rule>
     <rule>
      <from>/**</from>
      <to>/app/$1</to>
     </rule>
     <outbound-rule>
      <from>/app/**</from>
      <to>/$1</to>
     </outbound-rule> 
    </urlrewrite>
1
ответ дан Pablo Cantero 1 September 2018 в 09:48
поделиться

Мой собственный опыт с этой проблемой заключается в следующем. Большинство связанных с весной веб-страниц и книг, по-видимому, предполагают, что наиболее подходящий синтаксис следующий.

    <mvc:resources mapping="/resources/**" location="/resources/" />

Вышеупомянутый синтаксис предполагает, что вы можете разместить свои статические ресурсы (CSS, JavaScript, изображения) в папка с именем «resources» в корне вашего приложения, то есть /webapp/resources/.

Однако, по моему опыту (я использую Eclipse и плагин Tomcat), единственный подход, который работает, - это если вы поместите папку ресурсов внутри WEB_INF (или META-INF). Итак, синтаксис, который я рекомендую, следующий:

    <mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />

В вашем JSP (или аналогичном) ссылайтесь на ресурс следующим образом.

<script type="text/javascript"
        src="resources/my-javascript.js">
</script>

Не стоит забывать, что весь вопрос возник только потому, что я хотел, чтобы мой диспетчер диспетчера весны (фронт-контроллер) перехватил все, все динамическое. Итак, у меня есть следующее в моем web.xml.

<servlet>
    <servlet-name>front-controller</servlet-name>
    <servlet-class>
                org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    <!-- spring automatically discovers /WEB-INF/<servlet-name>-servlet.xml -->
</servlet>

<servlet-mapping>
    <servlet-name>front-controller</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Наконец, поскольку я использую текущие лучшие практики, у меня есть следующее в моем сервлет-сервлете xml (см. Выше).

<mvc:annotation-driven/>

И у меня есть следующее в моей фактической реализации контроллера, чтобы убедиться, что у меня есть метод по умолчанию для обработки всех входящих запросов.

@RequestMapping("/")

Надеюсь, это поможет.

7
ответ дан Puneet Lamba 1 September 2018 в 09:48
поделиться

Эта проблема решается весной 3.0.4.RELEASE, где вы можете использовать конфигурационный элемент <mvc:resources mapping="..." location="..."/> в конфигурационном файле весеннего диспетчера.

Проверить Документация по весне

47
ответ дан rozky 1 September 2018 в 09:48
поделиться

Я использовал оба способа, которые представляют собой urlrewrite и аннотацию, основанную на весеннем mvc 3.0.x, и обнаружили, что подход, основанный на аннотации, наиболее подходит, который является

<annotation-driven />

<resources mapping="/resources/**" location="/resources/" />

. В случае urlrewrite, определите много правил и некоторое время также получите исключение класса не найденное для UrlRewriteFilter, поскольку уже предоставили ему зависимость. Я обнаружил, что это происходит из-за наличия транзитивной зависимости, поэтому снова один шаг будет увеличен и должен будет исключить эту зависимость из pom.xml, используя

<exclusion></exclusion> tags.

. Таким образом, подход на основе аннотации будет хорошая сделка.

1
ответ дан Ruju 1 September 2018 в 09:48
поделиться

URLRewrite - это своего рода «взлом», если вы хотите это назвать. Что это значит, вы изобретаете колесо; так как есть уже существующие решения. Еще одна вещь, которую следует помнить, - Http Server = Статический контент и amp; Сервер приложений = динамический контент (так они были разработаны). Делегируя соответствующие обязанности каждому серверу, вы максимизируете эффективность ... но сейчас это, вероятно, всего лишь проблема в критически важных средах, и что-то вроде Tomcat, скорее всего, будет хорошо работать в обеих ролях большую часть времени; но все равно что-то иметь в виду, тем не менее.

2
ответ дан Stoney 1 September 2018 в 09:48
поделиться

Мой способ решения этой проблемы заключается в размещении всех ваших действий с определенным префиксом, подобным «сети» или «службе», и настроить, что все URL-адреса с этим префиксом будут перехватываться DispatcherServlet.

1
ответ дан Teja Kantamneni 1 September 2018 в 09:48
поделиться

Если я правильно понимаю вашу проблему, я думаю, что нашел решение вашей проблемы:

У меня была такая же проблема, когда был показан необработанный вывод без каких-либо CSS-стилей, javascripts или файлов jquery.

Я просто добавил сопоставления к сервлету по умолчанию. В файл web.xml добавлено следующее:

 <servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.css</url-pattern>
 </servlet-mapping>

 <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
 </servlet-mapping>

Это должно отфильтровывать запросы файла javascript и css из объекта DispatcherRequest.

Опять же, не уверен, что это что вы после, но это сработало для меня. Я думаю, что «default» - это имя сервлета по умолчанию в JBoss. Не слишком уверен, что это такое для других серверов.

18
ответ дан user243397 1 September 2018 в 09:48
поделиться

Для конфигурации весны на основе java вы можете использовать следующие

Использование ResourceHandlerRegistry , в котором хранятся регистрации обработчиков ресурсов для обслуживания статических ресурсов.

Дополнительная информация @ WebMvcConfigurerAdapter , который определяет методы обратного вызова для настройки конфигурации Java для Spring MVC с помощью @EnableWebMvc.

@EnableWebMvc
@Configurable
@ComponentScan("package.to.scan")
public class WebConfigurer extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static_resource_path/*.jpg").addResourceLocations("server_destination_path");

    }
0
ответ дан Vipul Panth 1 September 2018 в 09:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: