Большинство ответов здесь затрагивают этот вопрос в очень сухих технических терминах. Я хотел бы остановиться на этом в терминах, которые могут понять обычные люди.
Представьте, что вы пытаетесь нарезать пиццу. У вас есть роботизированный резак для пиццы, который может разрезать кусочки пиццы ровно пополам. Он может вдвое сократить целую пиццу, или он может сократить вдвое существующий кусочек, но в любом случае половина всегда точна.
У этого резца пиццы очень хорошие движения, и если вы начнете с целой пиццы, затем уменьшите вдвое и продолжайте вдвое уменьшать наименьший срез каждый раз, вы можете сделать половину 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.)
ч>
Поскольку я потратил много времени на эту проблему, я решил поделиться своим решением. Начиная с весны 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" />" />
Надеюсь, что это поможет: -)
Я знаю, что есть несколько конфигураций для использования статического содержимого, но мое решение заключается в том, что я просто создаю большую папку веб-приложений в вашем tomcat. Этот «bulk webapp» обслуживает только статическое содержимое без обслуживания приложений. Это безболезненное и простое решение для обслуживания статического содержимого для вашего фактического весеннего webapp.
Например, я использую две папки webapp на моем tomcat.
Если я хочу использовать javascript, я просто добавляю URI для своего javascript-файла.
EX> / resources / path / to / js / myjavascript.js
Для статических изображений я использую тот же метод.
EX> / resources / path / to /img/myimg.jpg
Наконец, я поставил «ограничение безопасности» на моем tomcat, чтобы заблокировать доступ к фактическому каталогу. Я помещал «никто» в список ограничений, чтобы страница генерировала «запрещенную ошибку 403», когда люди пытались получить доступ к пути статического содержимого.
Пока это работает очень хорошо для меня. Я также заметил, что многие популярные сайты, такие как Amazon, Twitter и Facebook, используют разные URI для обслуживания статического содержимого. Чтобы узнать это, просто щелкните правой кнопкой мыши на любом статическом содержимом и проверьте их URI.
Проблема связана с URLPattern
Измените свой шаблон URL на вашем сервлет-сопоставлении с "/" на "/ *"
В Spring 3.0.x добавьте следующее в ваш servlet-config.xml (файл, который настроен в web.xml как contextConfigLocation. Вам также нужно добавить пространство имен mvc, но просто Google для этого, t знает как!;)
Это работает для меня
<mvc:default-servlet-handler/>
С уважением
Аюб Малик
С весны 3 все ресурсы должны отображаться по-другому. Вы должны использовать тег, чтобы указать расположение ресурсов.
Пример:
<mvc:resources mapping="/resources/**" location="/resources/" />
Таким образом вы направляете сервлет диспетчера для поиска ресурсов каталога для поиска статического содержимого.
Я решил это так:
<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), который гораздо более портативен.
Это может быть достигнуто, по крайней мере, тремя способами.
Решения:
Для получения полного примера кода, как достичь этого пожалуйста, ответьте на мой ответ в другом сообщении: Как сопоставить запросы к HTML-файлу в Spring MVC?
Я нашел способ обойти это с помощью 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) не будет переписано.
<?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();
}
Это сделало реальную работу в моем случае
в 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>
...
У меня такая же проблема, и я нашел ответ Йориса очень полезным. Но дополнительно мне нужно добавить
<mvc:annotation-driven />
в файл конфигурации сервлета. Без этого сопоставление ресурсов не будет работать, и все обработчики перестанут работать. Надеюсь, это поможет кому-то.
После того, как вы столкнулись с одним и тем же процессом принятия решений, описанным здесь, я решил пойти с предложением 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>
Я только что справился с этой проблемой в 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>
Я просто добавлю три правила до правила весны по умолчанию (/ **) к 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>
Мой собственный опыт с этой проблемой заключается в следующем. Большинство связанных с весной веб-страниц и книг, по-видимому, предполагают, что наиболее подходящий синтаксис следующий.
<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("/")
Надеюсь, это поможет.
Эта проблема решается весной 3.0.4.RELEASE, где вы можете использовать конфигурационный элемент <mvc:resources mapping="..." location="..."/>
в конфигурационном файле весеннего диспетчера.
Проверить Документация по весне
Я использовал оба способа, которые представляют собой urlrewrite и аннотацию, основанную на весеннем mvc 3.0.x, и обнаружили, что подход, основанный на аннотации, наиболее подходит, который является
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
. В случае urlrewrite, определите много правил и некоторое время также получите исключение класса не найденное для UrlRewriteFilter, поскольку уже предоставили ему зависимость. Я обнаружил, что это происходит из-за наличия транзитивной зависимости, поэтому снова один шаг будет увеличен и должен будет исключить эту зависимость из pom.xml, используя
blockquote><exclusion></exclusion> tags.
. Таким образом, подход на основе аннотации будет хорошая сделка.
URLRewrite - это своего рода «взлом», если вы хотите это назвать. Что это значит, вы изобретаете колесо; так как есть уже существующие решения. Еще одна вещь, которую следует помнить, - Http Server = Статический контент и amp; Сервер приложений = динамический контент (так они были разработаны). Делегируя соответствующие обязанности каждому серверу, вы максимизируете эффективность ... но сейчас это, вероятно, всего лишь проблема в критически важных средах, и что-то вроде Tomcat, скорее всего, будет хорошо работать в обеих ролях большую часть времени; но все равно что-то иметь в виду, тем не менее.
Мой способ решения этой проблемы заключается в размещении всех ваших действий с определенным префиксом, подобным «сети» или «службе», и настроить, что все URL-адреса с этим префиксом будут перехватываться DispatcherServlet.
Если я правильно понимаю вашу проблему, я думаю, что нашел решение вашей проблемы:
У меня была такая же проблема, когда был показан необработанный вывод без каких-либо 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. Не слишком уверен, что это такое для других серверов.
Для конфигурации весны на основе 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");
}