001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.function.support; 018 019import java.util.List; 020 021import javax.servlet.http.HttpServletRequest; 022import javax.servlet.http.HttpServletResponse; 023 024import org.springframework.core.Ordered; 025import org.springframework.http.converter.HttpMessageConverter; 026import org.springframework.lang.Nullable; 027import org.springframework.util.Assert; 028import org.springframework.web.servlet.HandlerAdapter; 029import org.springframework.web.servlet.ModelAndView; 030import org.springframework.web.servlet.function.HandlerFunction; 031import org.springframework.web.servlet.function.RouterFunctions; 032import org.springframework.web.servlet.function.ServerRequest; 033import org.springframework.web.servlet.function.ServerResponse; 034 035/** 036 * {@code HandlerAdapter} implementation that supports {@link HandlerFunction}s. 037 * 038 * @author Arjen Poutsma 039 * @since 5.2 040 */ 041public class HandlerFunctionAdapter implements HandlerAdapter, Ordered { 042 043 private int order = Ordered.LOWEST_PRECEDENCE; 044 045 046 /** 047 * Specify the order value for this HandlerAdapter bean. 048 * <p>The default value is {@code Ordered.LOWEST_PRECEDENCE}, meaning non-ordered. 049 * @see org.springframework.core.Ordered#getOrder() 050 */ 051 public void setOrder(int order) { 052 this.order = order; 053 } 054 055 @Override 056 public int getOrder() { 057 return this.order; 058 } 059 060 @Override 061 public boolean supports(Object handler) { 062 return handler instanceof HandlerFunction; 063 } 064 065 @Nullable 066 @Override 067 public ModelAndView handle(HttpServletRequest servletRequest, 068 HttpServletResponse servletResponse, 069 Object handler) throws Exception { 070 071 072 HandlerFunction<?> handlerFunction = (HandlerFunction<?>) handler; 073 074 ServerRequest serverRequest = getServerRequest(servletRequest); 075 ServerResponse serverResponse = handlerFunction.handle(serverRequest); 076 077 return serverResponse.writeTo(servletRequest, servletResponse, 078 new ServerRequestContext(serverRequest)); 079 } 080 081 private ServerRequest getServerRequest(HttpServletRequest servletRequest) { 082 ServerRequest serverRequest = 083 (ServerRequest) servletRequest.getAttribute(RouterFunctions.REQUEST_ATTRIBUTE); 084 Assert.state(serverRequest != null, () -> "Required attribute '" + 085 RouterFunctions.REQUEST_ATTRIBUTE + "' is missing"); 086 return serverRequest; 087 } 088 089 @Override 090 public long getLastModified(HttpServletRequest request, Object handler) { 091 return -1L; 092 } 093 094 095 private static class ServerRequestContext implements ServerResponse.Context { 096 097 private final ServerRequest serverRequest; 098 099 100 public ServerRequestContext(ServerRequest serverRequest) { 101 this.serverRequest = serverRequest; 102 } 103 104 @Override 105 public List<HttpMessageConverter<?>> messageConverters() { 106 return this.serverRequest.messageConverters(); 107 } 108 } 109}