@Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; }
/** * Check the given request for supported methods and a required session, if any. * @param request current HTTP request * @throws ServletException if the request cannot be handled because a check failed * @since 4.2 */ protected final void checkRequest(HttpServletRequest request) throws ServletException { // Check whether we should support the request method. String method = request.getMethod(); if (this.supportedMethods != null && !this.supportedMethods.contains(method)) { throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods); } // Check whether a session is required. if (this.requireSession && request.getSession(false) == null) { throw new HttpSessionRequiredException("Pre-existing session required but none found"); } }
/** * Populate the model in the following order: * <ol> * <li>Retrieve "known" session attributes listed as {@code @SessionAttributes}. * <li>Invoke {@code @ModelAttribute} methods * <li>Find {@code @ModelAttribute} method arguments also listed as * {@code @SessionAttributes} and ensure they're present in the model raising * an exception if necessary. * </ol> * @param request the current request * @param container a container with the model to be initialized * @param handlerMethod the method for which the model is initialized * @throws Exception may arise from {@code @ModelAttribute} methods */ public void initModel(NativeWebRequest request, ModelAndViewContainer container, HandlerMethod handlerMethod) throws Exception { Map<String, ?> sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request); container.mergeAttributes(sessionAttributes); invokeModelAttributeMethods(request, container); for (String name : findSessionAttributeArguments(handlerMethod)) { if (!container.containsAttribute(name)) { Object value = this.sessionAttributesHandler.retrieveAttribute(request, name); if (value == null) { throw new HttpSessionRequiredException("Expected session attribute '" + name + "'", name); } container.addAttribute(name, value); } } }
/** * Handle the case where no request handler method was found for the particular HTTP request method. * <p>The default implementation logs a warning, sends an HTTP 405 error, sets the "Allow" header, * and returns an empty {@code ModelAndView}. Alternatively, a fallback view could be chosen, * or the HttpRequestMethodNotSupportedException could be rethrown as-is. * @param ex the HttpRequestMethodNotSupportedException to be handled * @param request current HTTP request * @param response current HTTP response * @param handler the executed handler, or {@code null} if none chosen * at the time of the exception (for example, if multipart resolution failed) * @return an empty ModelAndView indicating the exception was handled * @throws IOException potentially thrown from {@link HttpServletResponse#sendError} */ protected ModelAndView handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws IOException { String[] supportedMethods = ex.getSupportedMethods(); if (supportedMethods != null) { response.setHeader("Allow", StringUtils.arrayToDelimitedString(supportedMethods, ", ")); } response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, ex.getMessage()); return new ModelAndView(); }
@Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Assert.state(this.target != null, "No HttpRequestHandler available"); LocaleContextHolder.setLocale(request.getLocale()); try { this.target.handleRequest(request, response); } catch (HttpRequestMethodNotSupportedException ex) { String[] supportedMethods = ex.getSupportedMethods(); if (supportedMethods != null) { response.setHeader("Allow", StringUtils.arrayToDelimitedString(supportedMethods, ", ")); } response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, ex.getMessage()); } finally { LocaleContextHolder.resetLocaleContext(); } }
/** * Customize the response for HttpRequestMethodNotSupportedException. * <p>This method logs a warning, sets the "Allow" header, and delegates to * {@link #handleExceptionInternal}. * @param ex the exception * @param headers the headers to be written to the response * @param status the selected response status * @param request the current request * @return a {@code ResponseEntity} instance */ protected ResponseEntity<Object> handleHttpRequestMethodNotSupported( HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { pageNotFoundLogger.warn(ex.getMessage()); Set<HttpMethod> supportedMethods = ex.getSupportedHttpMethods(); if (!CollectionUtils.isEmpty(supportedMethods)) { headers.setAllow(supportedMethods); } return handleExceptionInternal(ex, null, headers, status, request); }
/** * Processes the incoming Hessian request and creates a Hessian response. */ @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!"POST".equals(request.getMethod())) { throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[] {"POST"}, "HessianServiceExporter only supports POST requests"); } response.setContentType(CONTENT_TYPE_HESSIAN); try { invoke(request.getInputStream(), response.getOutputStream()); } catch (Throwable ex) { throw new NestedServletException("Hessian skeleton invocation failed", ex); } }
/** * Customize the response for HttpMediaTypeNotSupportedException. * <p>This method sets the "Accept" header and delegates to * {@link #handleExceptionInternal}. * @param ex the exception * @param headers the headers to be written to the response * @param status the selected response status * @param request the current request * @return a {@code ResponseEntity} instance */ protected ResponseEntity<Object> handleHttpMediaTypeNotSupported( HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { List<MediaType> mediaTypes = ex.getSupportedMediaTypes(); if (!CollectionUtils.isEmpty(mediaTypes)) { headers.setAccept(mediaTypes); } return handleExceptionInternal(ex, null, headers, status, request); }
/** * Override to provide handling when a key is not resolved via. * {@link #lookupMediaType}. Sub-classes can take further steps to * determine the media type(s). If a MediaType is returned from * this method it will be added to the cache in the base class. */ @Nullable protected MediaType handleNoMatch(NativeWebRequest request, String key) throws HttpMediaTypeNotAcceptableException { if (!isUseRegisteredExtensionsOnly()) { Optional<MediaType> mediaType = MediaTypeFactory.getMediaType("file." + key); if (mediaType.isPresent()) { return mediaType.get(); } } if (isIgnoreUnknownExtensions()) { return null; } throw new HttpMediaTypeNotAcceptableException(getAllMediaTypes()); }
@Test public void handleHttpRequestMethodNotSupported() { HttpRequestMethodNotSupportedException ex = new HttpRequestMethodNotSupportedException("GET", new String[]{"POST", "PUT"}); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertNotNull("No ModelAndView returned", mav); assertTrue("No Empty ModelAndView returned", mav.isEmpty()); assertEquals("Invalid status code", 405, response.getStatus()); assertEquals("Invalid Allow header", "POST, PUT", response.getHeader("Allow")); }
private void testHttpMediaTypeNotSupportedException(String url) throws Exception { try { MockHttpServletRequest request = new MockHttpServletRequest("PUT", url); request.setContentType("application/json"); this.handlerMapping.getHandler(request); fail("HttpMediaTypeNotSupportedException expected"); } catch (HttpMediaTypeNotSupportedException ex) { assertEquals("Invalid supported consumable media types", Collections.singletonList(new MediaType("application", "xml")), ex.getSupportedMediaTypes()); } }
@Test public void getHandlerRequestMethodNotAllowed() throws Exception { try { MockHttpServletRequest request = new MockHttpServletRequest("POST", "/bar"); this.handlerMapping.getHandler(request); fail("HttpRequestMethodNotSupportedException expected"); } catch (HttpRequestMethodNotSupportedException ex) { assertArrayEquals("Invalid supported methods", new String[]{"GET", "HEAD"}, ex.getSupportedMethods()); } }
@Test public void httpRequestMethodNotSupported() { List<String> supported = Arrays.asList("POST", "DELETE"); Exception ex = new HttpRequestMethodNotSupportedException("GET", supported); ResponseEntity<Object> responseEntity = testException(ex); assertEquals(EnumSet.of(HttpMethod.POST, HttpMethod.DELETE), responseEntity.getHeaders().getAllow()); }
@Test public void httpMediaTypeNotAcceptable() { Exception ex = new HttpMediaTypeNotAcceptableException(""); testException(ex); }
@Test public void handleHttpMediaTypeNotSupported() { HttpMediaTypeNotSupportedException ex = new HttpMediaTypeNotSupportedException(new MediaType("text", "plain"), Collections.singletonList(new MediaType("application", "pdf"))); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertNotNull("No ModelAndView returned", mav); assertTrue("No Empty ModelAndView returned", mav.isEmpty()); assertEquals("Invalid status code", 415, response.getStatus()); assertEquals("Invalid Accept header", "application/pdf", response.getHeader("Accept")); }
@Test public void handleHttpMediaTypeNotSupported() { List<MediaType> acceptable = Arrays.asList(MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_XML); Exception ex = new HttpMediaTypeNotSupportedException(MediaType.APPLICATION_JSON, acceptable); ResponseEntity<Object> responseEntity = testException(ex); assertEquals(acceptable, responseEntity.getHeaders().getAccept()); }
@Test public void getHandlerTestInvalidContentType() throws Exception { try { MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/person/1"); request.setContentType("bogus"); this.handlerMapping.getHandler(request); fail("HttpMediaTypeNotSupportedException expected"); } catch (HttpMediaTypeNotSupportedException ex) { assertEquals("Invalid mime type \"bogus\": does not contain '/'", ex.getMessage()); } }
private void testHttpMediaTypeNotAcceptableException(String url) throws Exception { try { MockHttpServletRequest request = new MockHttpServletRequest("GET", url); request.addHeader("Accept", "application/json"); this.handlerMapping.getHandler(request); fail("HttpMediaTypeNotAcceptableException expected"); } catch (HttpMediaTypeNotAcceptableException ex) { assertEquals("Invalid supported producible media types", Collections.singletonList(new MediaType("application", "xml")), ex.getSupportedMediaTypes()); } }
/** * Check the given request for supported methods and a required session, if any. * @param request current HTTP request * @throws ServletException if the request cannot be handled because a check failed * @since 4.2 */ protected final void checkRequest(HttpServletRequest request) throws ServletException { // Check whether we should support the request method. String method = request.getMethod(); if (this.supportedMethods != null && !this.supportedMethods.contains(method)) { throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods); } // Check whether a session is required. if (this.requireSession && request.getSession(false) == null) { throw new HttpSessionRequiredException("Pre-existing session required but none found"); } }
@Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; }