Подтвердить что ты не робот

Spring throwing HttpMediaTypeNotAcceptableException: не удалось найти приемлемое представление из-за точки в URL-адресе

Финальное редактирование

Итак, после изучения этого, потому что ответ не совсем сделал, так как с тем, что я видел, я обнаружил, что Spring делает некоторые странные вещи с расширением соответствия. Если я отправлю запрос, подобный этому byNameOrAtlName/myStringHere.1 или этому byNameOrAtlName/myStringHere.12, все будет в порядке, но byNameOrAtlName/myStringHere.123 заставляет его ломаться, как и byNameOrAtlName/myStringHere.com, но byNameOrAtlName/myStringHere.co в порядке, но byNameOrAtlName/myStringHere.c нет.

В общем, я не знаю, что использует логика Spring для определения материала расширения, но для определенных расширений {varName:.+} работает как своего рода работа, но похоже, что вам нужно полностью отключить суффикс точечного файла чтобы действительно обойти это.


Использование Spring 4.1.6

Spring выбрасывает следующее исключение org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

У меня есть следующий код, и все работает, если строка (имя) не имеет в ней периода.

@RestController
@RequestMapping(value = "/foo/")
public class Testing{
    @RequestMapping(value = "byNameOrAltName/{name:.+}", method = RequestMethod.GET)
    @Transactional(readOnly = true)
    public Collection<MyDTO> getByNameOrAltNAme(@PathVariable("name") String name) {
        return myRepo.getMyDTOsByNameOrAtlName(name);
    }
}

Итак, это работает. http://localhost:8080/data/foo/byNameOrAtlName/myStringHere, но если я это сделаю, он терпит неудачу http://localhost:8080/data/foo/byNameOrAtlName/myStringHere.fluffy

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

Любые идеи относительно того, почему Spring выбрасывает это?

ИЗМЕНИТЬ

Вот мой журнал отладки:

21:32:09,118 DEBUG work.orm.jpa.support.OpenEntityManagerInViewFilter: 161 - Opening JPA EntityManager in OpenEntityManagerInViewFilter
21:32:09,118 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/r2d2/**'
21:32:09,118 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
21:32:09,118 DEBUG y.web.context.HttpSessionSecurityContextRepository: 192 - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: '[email protected]da7134: Authentication: org.springframew[email protected]3eda7134: REDACTED
21:32:09,122 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 2 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
21:32:09,122 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
21:32:09,122 DEBUG ework.security.web.header.writers.HstsHeaderWriter: 128 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.se[email protected]518864fd
21:32:09,122 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
21:32:09,122 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/logout'
21:32:09,122 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
21:32:09,122 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 131 - Request 'GET /data/restaurant/supplier/bynameoraltname/quill.com' doesn't match 'POST /login
21:32:09,122 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
21:32:09,122 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
21:32:09,122 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
21:32:09,122 DEBUG y.web.authentication.AnonymousAuthenticationFilter: 106 - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframew[email protected]3eda7134: REDACTED
21:32:09,123 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
21:32:09,123 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
21:32:09,123 DEBUG  org.springframework.security.web.FilterChainProxy: 324 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/login.html'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/index.html'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/*/css/**'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/*/fonts/**'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/*/img/**'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/*/lib/**'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/*/vendor/**'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/sales/**'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/registration/termsofservice.html'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/registration/privacypolicy.html'
21:32:09,123 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/restaurantui/useractivation.html**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/restaurantui/index.html'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/basicuseractivation/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/orderconfirmation/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/supplieruseractivation/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/restaurantuseractivation/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/useractivation/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/user/passwordresetrequest'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/user/changepasswordfortoken/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/user/checkpasswordtokenvalidity/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/signup/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/downloads/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/unsubscribe.html'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/restaurant/emailsubscriptions/unsubscribe/**'
21:32:09,124 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/adminui/**'
21:32:09,125 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/admin*'
21:32:09,125 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/confirm/**'
21:32:09,125 DEBUG rk.security.web.util.matcher.AntPathRequestMatcher: 151 - Checking match of request : '/data/restaurant/supplier/bynameoraltname/quill.com'; against '/data/**'
21:32:09,125 DEBUG ity.web.access.intercept.FilterSecurityInterceptor: 218 - Secure object: FilterInvocation: URL: /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116; Attributes: [isAuthenticated()]
21:32:09,125 DEBUG ity.web.access.intercept.FilterSecurityInterceptor: 347 - Previously Authenticated: org.springframew[email protected]3eda7134: REDACTED
21:32:09,126 DEBUG ingframework.security.access.vote.AffirmativeBased:  65 - Voter: org.sp[email protected]3b97d645, returned: 1
21:32:09,126 DEBUG ity.web.access.intercept.FilterSecurityInterceptor: 242 - Authorization successful
21:32:09,126 DEBUG ity.web.access.intercept.FilterSecurityInterceptor: 255 - RunAsManager did not change Authentication object
21:32:09,126 DEBUG  org.springframework.security.web.FilterChainProxy: 309 - /data/restaurant/supplier/byNameOrAltName/quill.com?_=1434072729116 reached end of additional filter chain; proceeding with original chain
21:32:09,126 DEBUG  org.springframework.web.servlet.DispatcherServlet: 861 - DispatcherServlet with name 'Spring MVC Servlet' processing GET request for [/data/restaurant/supplier/byNameOrAltName/quill.com]
21:32:09,126 DEBUG mvc.method.annotation.RequestMappingHandlerMapping: 294 - Looking up handler method for path /restaurant/supplier/byNameOrAltName/quill.com
21:32:09,127 DEBUG mvc.method.annotation.RequestMappingHandlerMapping: 299 - Returning handler method [public java.util.Collection<com.siftit.webservices.personae.restaurant.dtos.SupplierDTO> com.siftit.webservices.personae.restaurant.RestaurantSupplierWebService.getByNameOrAltNAme(java.lang.String)]
21:32:09,128 DEBUG k.beans.factory.support.DefaultListableBeanFactory: 248 - Returning cached instance of singleton bean 'restaurantSupplierWebService'
21:32:09,128 DEBUG  org.springframework.web.servlet.DispatcherServlet: 947 - Last-Modified value for [/data/restaurant/supplier/byNameOrAltName/quill.com] is: -1
21:32:09,128 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,128 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 367 - Creating new transaction with name [com.siftit.webservices.security.WebServiceInterceptor.preHandle]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
21:32:09,128 DEBUG rg.springframework.jdbc.datasource.DataSourceUtils: 153 - Setting JDBC Connection [[email protected]] read-only
21:32:09,128 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 403 - Exposing JPA transaction as JDBC transaction [org.springframewo[email protected]6d32e04]
21:32:09,128 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,129 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 472 - Participating in existing transaction
21:32:09,129 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,129 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 472 - Participating in existing transaction
21:32:09,140 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 755 - Initiating transaction commit
21:32:09,140 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 512 - Committing JPA transaction on EntityManager [[email protected]]
21:32:09,141 DEBUG rg.springframework.jdbc.datasource.DataSourceUtils: 222 - Resetting read-only flag of JDBC Connection [[email protected]]
21:32:09,141 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 605 - Not closing pre-bound JPA EntityManager after transaction
21:32:09,142 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,142 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 367 - Creating new transaction with name [com.siftit.webservices.personae.restaurant.RestaurantSupplierWebService.getByNameOrAltNAme]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
21:32:09,142 DEBUG rg.springframework.jdbc.datasource.DataSourceUtils: 153 - Setting JDBC Connection [[email protected]] read-only
21:32:09,142 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 403 - Exposing JPA transaction as JDBC transaction [org.springframewo[email protected]32689afc]
21:32:09,143 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,143 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 472 - Participating in existing transaction
21:32:09,143 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,143 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 472 - Participating in existing transaction
21:32:09,144 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,144 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 472 - Participating in existing transaction
21:32:09,144 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 334 - Found thread-bound EntityManager [[email protected]] for JPA transaction
21:32:09,144 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 472 - Participating in existing transaction
21:32:09,146 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 755 - Initiating transaction commit
21:32:09,146 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 512 - Committing JPA transaction on EntityManager [[email protected]]
21:32:09,146 DEBUG rg.springframework.jdbc.datasource.DataSourceUtils: 222 - Resetting read-only flag of JDBC Connection [[email protected]]
21:32:09,147 DEBUG  org.springframework.orm.jpa.JpaTransactionManager: 605 - Not closing pre-bound JPA EntityManager after transaction
21:32:09,147 DEBUG ethod.annotation.ExceptionHandlerExceptionResolver: 134 - Resolving exception from handler [public java.util.Collection<com.siftit.webservices.personae.restaurant.dtos.SupplierDTO> com.siftit.webservices.personae.restaurant.RestaurantSupplierWebService.getByNameOrAltNAme(java.lang.String)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
21:32:09,147 DEBUG k.beans.factory.support.DefaultListableBeanFactory: 248 - Returning cached instance of singleton bean 'globalWebServiceExceptionHandler'
21:32:09,147 DEBUG ethod.annotation.ExceptionHandlerExceptionResolver: 360 - Invoking @ExceptionHandler method: public java.lang.Object com.siftit.webservices.GlobalWebServiceExceptionHandler.defaultErrorHandler(javax.servlet.http.HttpServletRequest,java.lang.Exception) throws java.lang.Exception
21:32:09,155 DEBUG thod.annotation.RequestResponseBodyMethodProcessor: 163 - Written [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation] as "application/x-msdownload" using [[email protected]4c8f9d]
21:32:09,155 DEBUG  org.springframework.web.servlet.DispatcherServlet:1034 - Null ModelAndView returned to DispatcherServlet with name 'Spring MVC Servlet': assuming HandlerAdapter completed request handling
21:32:09,155 DEBUG  org.springframework.web.servlet.DispatcherServlet: 996 - Successfully completed request
21:32:09,155 DEBUG ork.security.web.access.ExceptionTranslationFilter: 116 - Chain processed normally
21:32:09,155 DEBUG urity.web.context.SecurityContextPersistenceFilter: 105 - SecurityContextHolder now cleared, as request processing completed
21:32:09,155 DEBUG work.orm.jpa.support.OpenEntityManagerInViewFilter: 186 - Closing JPA EntityManager in OpenEntityManagerInViewFilter
21:32:09,156 DEBUG .springframework.orm.jpa.EntityManagerFactoryUtils: 432 - Closing JPA EntityManager

Вот мои заголовки запросов:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Cookie:JSESSIONID=BLABLABLABLA; subscriptionType=PREMIUM; userType=ROLE_ADMIN
DNT:1
Host:localhost:8080
Pragma:no-cache
Referer:http://localhost:8080/restaurantui/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
4b9b3361

Ответ 1

Spring обрабатывает часть после точки в качестве суффикса файла, чтобы попытаться определить, какой тип ответа вы действительно хотите. Здесь - достойная запись в согласовании содержимого в Spring.

Так что происходит, что Spring пытается представить результат в типе контента, к которому он не может найти конвертер.

Чтобы решить эту проблему, вам нужно сообщить Spring об отключении суффикса на основе содержимого:

@Configuration
public class ContentNegotiationConfig extends WebMvcConfigurerAdapter {
    @Override
    void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
        // Turn off suffix-based content negotiation
        configurer.favorPathExtension(false);
    }
}

Update:

Я вырыл немного глубже, и я думаю, что могу объяснить, что происходит.

Конфигурация по умолчанию игнорирует неизвестные суффиксы пути, поэтому для объяснения этого нам нужно знать, как Spring определяет, что суффикс пути неизвестен и что сводится к этому фрагменту кода в PathExtensionContentNegotiationStrategy:

@Override
protected MediaType handleNoMatch(NativeWebRequest webRequest, String extension)
        throws HttpMediaTypeNotAcceptableException {

    if (this.useJaf) {
        MediaType jafMediaType = JafMediaTypeFactory.getMediaType("file." + extension);
        if (jafMediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(jafMediaType)) {
            return jafMediaType;
        }
    }
    if (!this.ignoreUnknownExtensions) {
        throw new HttpMediaTypeNotAcceptableException(getAllMediaTypes());
    }
    return null;
}

Итак, что происходит, вероятно, что Java Activation Framework распознает некоторые ваши суффиксы и возвращает для них тип носителя. Расширение .c, вероятно, возвращает текст /x -c, поскольку это вызывает исключение.