下面列出了javax.servlet.http.PushBuilder#org.springframework.web.method.support.ModelAndViewContainer 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Nullable
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
modelFactory.updateModel(webRequest, mavContainer);
if (mavContainer.isRequestHandled()) {
return null;
}
ModelMap model = mavContainer.getModel();
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
if (model instanceof RedirectAttributes) {
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (request != null) {
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
}
return mav;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
ModelMap model = mavContainer.getModel();
if (model.size() > 0) {
int lastIndex = model.size()-1;
String lastKey = new ArrayList<String>(model.keySet()).get(lastIndex);
if (lastKey.startsWith(BindingResult.MODEL_KEY_PREFIX)) {
return model.get(lastKey);
}
}
throw new IllegalStateException(
"An Errors/BindingResult argument is expected to be declared immediately after the model attribute, " +
"the @RequestBody or the @RequestPart arguments to which they apply: " + parameter.getMethod());
}
/**
* springmvc提供的render方法
*
*/
public void springMvcRender(Object returnValue){
try{
// modelAndViewContainer init
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
ServletWebRequest webRequest = new ServletWebRequest(AoomsContext.getRequest(), AoomsContext.getResponse());
// get ApplicationContext
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(AoomsContext.getServletContext());
// get RequestMappingHandlerAdapter Bean
RequestMappingHandlerAdapter requestMappingHandlerAdapter = (RequestMappingHandlerAdapter)ac1.getBean("requestMappingHandlerAdapter");
// init handlerMethodReturnValueHandlerComposite
HandlerMethodReturnValueHandlerComposite handlerMethodReturnValueHandlerComposite = new HandlerMethodReturnValueHandlerComposite();
handlerMethodReturnValueHandlerComposite.addHandlers(requestMappingHandlerAdapter.getReturnValueHandlers());
// render
HandlerMethod method = AoomsContext.getMethodHandler();
handlerMethodReturnValueHandlerComposite.handleReturnValue(returnValue, method.getReturnType(), modelAndViewContainer, webRequest);
} catch (Exception ex){
throw AoomsExceptions.create("springmvc render error",ex);
}
}
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
messageConverter = mock(HttpMessageConverter.class);
given(messageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.TEXT_PLAIN));
processor = new RequestResponseBodyMethodProcessor(Collections.<HttpMessageConverter<?>>singletonList(messageConverter));
Method methodHandle1 = getClass().getMethod("handle1", String.class, Integer.TYPE);
paramRequestBodyString = new MethodParameter(methodHandle1, 0);
paramInt = new MethodParameter(methodHandle1, 1);
returnTypeString = new MethodParameter(methodHandle1, -1);
returnTypeInt = new MethodParameter(getClass().getMethod("handle2"), -1);
returnTypeStringProduces = new MethodParameter(getClass().getMethod("handle3"), -1);
paramValidBean = new MethodParameter(getClass().getMethod("handle4", SimpleBean.class), 0);
paramStringNotRequired = new MethodParameter(getClass().getMethod("handle5", String.class), 0);
mavContainer = new ModelAndViewContainer();
servletRequest = new MockHttpServletRequest();
servletRequest.setMethod("POST");
webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
}
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue instanceof View){
View view = (View) returnValue;
mavContainer.setView(view);
if (view instanceof SmartView && ((SmartView) view).isRedirectView()) {
mavContainer.setRedirectModelScenario(true);
}
}
else if (returnValue != null) {
// should not happen
throw new UnsupportedOperationException("Unexpected return type: " +
returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
}
}
@Test
public void updateModelBindingResult() throws Exception {
String commandName = "attr1";
Object command = new Object();
ModelAndViewContainer container = new ModelAndViewContainer();
container.addAttribute(commandName, command);
WebDataBinder dataBinder = new WebDataBinder(command, commandName);
WebDataBinderFactory binderFactory = mock(WebDataBinderFactory.class);
given(binderFactory.createBinder(this.webRequest, command, commandName)).willReturn(dataBinder);
ModelFactory modelFactory = new ModelFactory(null, binderFactory, this.attributeHandler);
modelFactory.updateModel(this.webRequest, container);
assertEquals(command, container.getModel().get(commandName));
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + commandName;
assertSame(dataBinder.getBindingResult(), container.getModel().get(bindingResultKey));
assertEquals(2, container.getModel().size());
}
@Test
public void handlesSuccess() throws Exception {
final AtomicReference<Object> value = new AtomicReference<>();
ListenableFuture<String> future = Futures.immediateFuture("42");
GuavaLFReturnValueHandler handler = new GuavaLFReturnValueHandler() {
@Override
protected void startDeferredResultProcessing(ModelAndViewContainer mavContainer, NativeWebRequest webRequest, DeferredResult<Object> deferredResult) throws Exception {
value.set(deferredResult.getResult());
}
};
handler.handleReturnValue(future, null, null, null);
assertThat(value.get()).isEqualTo("42");
}
/**
* Throws MethodArgumentNotValidException if validation fails.
* @throws HttpMessageNotReadableException if {@link RequestBody#required()}
* is {@code true} and there is no body content or if there is no suitable
* converter to read the content with.
*/
@Override
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
parameter = parameter.nestedIfOptional();
Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());
String name = Conventions.getVariableNameForParameter(parameter);
if (binderFactory != null) {
WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
if (arg != null) {
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
if (mavContainer != null) {
mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
}
}
return adaptArgumentIfNecessary(arg, parameter);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest;
HttpServletRequest request = servletWebRequest.getRequest();
String contentType = request.getHeader("Content-Type");
MediaType mediaType = MediaType.parseMediaType(contentType);
// 获取编码
Charset charset = mediaType.getCharset() == null ? Charset.forName("UTF-8") : mediaType.getCharset();
// 获取输入流
InputStream inputStream = request.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
// 输入流转换为 Properties
Properties properties = new Properties();
properties.load(inputStreamReader);
return properties;
}
@Override
public ClientAppUserAccessToken resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
String tokenStr = Strings.trimToEmpty(webRequest.getHeader(HttpHeaders.AUTHORIZATION));
if (!tokenStr.startsWith("Bearer ")) {
throw new MissingBearerTokenException();
}
String token = tokenStr.substring("Bearer ".length(), tokenStr.length()).trim();
Optional<ClientAppUserAccessToken> accessToken = clientAppService.verifyAccessToken(token);
if (!accessToken.isPresent()) {
throw new InvalidTokenException();
}
RequiredScope requiredScope = parameter.getMethodAnnotation(RequiredScope.class);
if (!accessToken.get().containsScope(requiredScope.value())) {
throw new InsufficientScopeException(requiredScope.value());
}
return accessToken.get();
}
@Before
public void setup() throws Exception {
processor = new ServletModelAttributeMethodProcessor(false);
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(new DefaultConversionService());
binderFactory = new ServletRequestDataBinderFactory(null, initializer);
mavContainer = new ModelAndViewContainer();
request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request);
Method method = getClass().getDeclaredMethod("modelAttribute",
TestBean.class, TestBeanWithoutStringConstructor.class, Optional.class);
testBeanModelAttr = new MethodParameter(method, 0);
testBeanWithoutStringConstructorModelAttr = new MethodParameter(method, 1);
testBeanWithOptionalModelAttr = new MethodParameter(method, 2);
}
@Before
public void setUp() throws Exception {
this.processor = new ServletModelAttributeMethodProcessor(false);
Method method = getClass().getDeclaredMethod("modelAttribute",
TestBean.class, TestBeanWithoutStringConstructor.class, Optional.class);
this.testBeanModelAttr = new MethodParameter(method, 0);
this.testBeanWithoutStringConstructorModelAttr = new MethodParameter(method, 1);
this.testBeanWithOptionalModelAttr = new MethodParameter(method, 2);
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(new DefaultConversionService());
this.binderFactory = new ServletRequestDataBinderFactory(null, initializer);
this.mavContainer = new ModelAndViewContainer();
this.request = new MockHttpServletRequest();
this.webRequest = new ServletWebRequest(request);
}
@Before
public void setUp() throws Exception {
this.resolver = new MatrixVariableMethodArgumentResolver();
Method method = getClass().getMethod("handle", String.class, List.class, int.class);
this.paramString = new MethodParameter(method, 0);
this.paramColors = new MethodParameter(method, 1);
this.paramYear = new MethodParameter(method, 2);
this.paramColors.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer());
this.mavContainer = new ModelAndViewContainer();
this.request = new MockHttpServletRequest();
this.webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
Map<String, MultiValueMap<String, String>> params = new LinkedHashMap<String, MultiValueMap<String, String>>();
this.request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, params);
}
@Test
public void updateModelSessionAttributesSaved() throws Exception {
String attributeName = "sessionAttr";
String attribute = "value";
ModelAndViewContainer container = new ModelAndViewContainer();
container.addAttribute(attributeName, attribute);
WebDataBinder dataBinder = new WebDataBinder(attribute, attributeName);
WebDataBinderFactory binderFactory = mock(WebDataBinderFactory.class);
given(binderFactory.createBinder(this.webRequest, attribute, attributeName)).willReturn(dataBinder);
ModelFactory modelFactory = new ModelFactory(null, binderFactory, this.sessionAttrsHandler);
modelFactory.updateModel(this.webRequest, container);
assertEquals(attribute, container.getModel().get(attributeName));
assertEquals(attribute, this.sessionAttributeStore.retrieveAttribute(this.webRequest, attributeName));
}
@Override
public Object resolveArgument(
MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
String requestPath = ((ServletWebRequest) webRequest).getRequest().getPathInfo();
String slug = requestPath
.substring(0, requestPath.indexOf("/", 1))
.replaceAll("^/", "");
return gitRepositoryFinder.findBySlug(slug)
.orElseThrow(NotFoundException::new);
}
/**
* Return a Map with all URI template variables or an empty map.
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
@SuppressWarnings("unchecked")
Map<String, String> uriTemplateVars =
(Map<String, String>) webRequest.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
if (!CollectionUtils.isEmpty(uriTemplateVars)) {
return new LinkedHashMap<String, String>(uriTemplateVars);
}
else {
return Collections.emptyMap();
}
}
@Test
public void updateModelSessionAttributesRemoved() throws Exception {
String attributeName = "sessionAttr";
String attribute = "value";
ModelAndViewContainer container = new ModelAndViewContainer();
container.addAttribute(attributeName, attribute);
// Store and resolve once (to be "remembered")
this.sessionAttributeStore.storeAttribute(this.webRequest, attributeName, attribute);
this.sessionAttrsHandler.isHandlerSessionAttribute(attributeName, null);
WebDataBinder dataBinder = new WebDataBinder(attribute, attributeName);
WebDataBinderFactory binderFactory = mock(WebDataBinderFactory.class);
given(binderFactory.createBinder(this.webRequest, attribute, attributeName)).willReturn(dataBinder);
container.getSessionStatus().setComplete();
ModelFactory modelFactory = new ModelFactory(null, binderFactory, this.sessionAttrsHandler);
modelFactory.updateModel(this.webRequest, container);
assertEquals(attribute, container.getModel().get(attributeName));
assertNull(this.sessionAttributeStore.retrieveAttribute(this.webRequest, attributeName));
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue instanceof CharSequence) {
String viewName = returnValue.toString();
mavContainer.setViewName(viewName);
if (isRedirectViewName(viewName)) {
mavContainer.setRedirectModelScenario(true);
}
}
else if (returnValue != null){
// should not happen
throw new UnsupportedOperationException("Unexpected return type: " +
returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
}
}
/**
* 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 mavContainer 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 mavContainer, HandlerMethod handlerMethod)
throws Exception {
Map<String, ?> sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request);
mavContainer.mergeAttributes(sessionAttributes);
invokeModelAttributeMethods(request, mavContainer);
for (String name : findSessionAttributeArguments(handlerMethod)) {
if (!mavContainer.containsAttribute(name)) {
Object value = this.sessionAttributesHandler.retrieveAttribute(request, name);
if (value == null) {
throw new HttpSessionRequiredException("Expected session attribute '" + name + "'");
}
mavContainer.addAttribute(name, value);
}
}
}
/**
* Delegate to the {@link WebArgumentResolver} instance.
* @throws IllegalStateException if the resolved value is not assignable
* to the method parameter.
*/
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
Class<?> paramType = parameter.getParameterType();
Object result = this.adaptee.resolveArgument(parameter, webRequest);
if (result == WebArgumentResolver.UNRESOLVED || !ClassUtils.isAssignableValue(paramType, result)) {
throw new IllegalStateException(
"Standard argument type [" + paramType.getName() + "] in method " + parameter.getMethod() +
"resolved to incompatible value of type [" + (result != null ? result.getClass() : null) +
"]. Consider declaring the argument type in a less specific fashion.");
}
return result;
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
final AsyncResponseEntity<?> asyncResponseEntity = AsyncResponseEntity.class.cast(returnValue);
Observable<?> observable = asyncResponseEntity.getObservable();
Single<?> single = asyncResponseEntity.getSingle();
MultiValueMap<String, String> headers = asyncResponseEntity.getHeaders();
HttpStatus status = asyncResponseEntity.getStatus();
if(observable != null)
WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(new ObservableDeferredResult<>(observable, headers, status), mavContainer);
else if(single != null)
WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(new SingleDeferredResult<>(single, headers, status), mavContainer);
}
@Override
public Client resolveArgument(final MethodParameter parameter,
final ModelAndViewContainer mavContainer,
final NativeWebRequest request,
final WebDataBinderFactory binderFactory) {
final String clientId = authorizationService.getSubject().map(Subject::getName)
.orElse(SecuritySettings.UNAUTHENTICATED_CLIENT_ID);
if (settings.getAuthMode() == SecuritySettings.AuthMode.OFF) {
return new FullAccessClient(clientId);
} else {
if (clientId.equals(settings.getAdminClientId())) {
return new FullAccessClient(FULL_ACCESS_CLIENT_ID);
} else if (!authorizationService.getSubject().isPresent()) {
throw new UnauthorizedUserException("Client unauthorized");
} else {
return new NakadiClient(clientId, getRealm());
}
}
}
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
return;
}
else if (returnValue instanceof Model) {
mavContainer.addAllAttributes(((Model) returnValue).asMap());
}
else {
// should not happen
throw new UnsupportedOperationException("Unexpected return type: " +
returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
}
}
@Before
public void setUp() throws Exception {
Method method = getClass().getDeclaredMethod("handle", List.class,
SimpleBean.class, MultiValueMap.class, String.class);
paramGenericList = new MethodParameter(method, 0);
paramSimpleBean = new MethodParameter(method, 1);
paramMultiValueMap = new MethodParameter(method, 2);
paramString = new MethodParameter(method, 3);
returnTypeString = new MethodParameter(method, -1);
mavContainer = new ModelAndViewContainer();
servletRequest = new MockHttpServletRequest();
servletRequest.setMethod("POST");
servletResponse = new MockHttpServletResponse();
webRequest = new ServletWebRequest(servletRequest, servletResponse);
this.binderFactory = new ValidatingBinderFactory();
}
@Test
public void updateModelBindingResult() throws Exception {
String commandName = "attr1";
Object command = new Object();
ModelAndViewContainer container = new ModelAndViewContainer();
container.addAttribute(commandName, command);
WebDataBinder dataBinder = new WebDataBinder(command, commandName);
WebDataBinderFactory binderFactory = mock(WebDataBinderFactory.class);
given(binderFactory.createBinder(this.webRequest, command, commandName)).willReturn(dataBinder);
ModelFactory modelFactory = new ModelFactory(null, binderFactory, this.attributeHandler);
modelFactory.updateModel(this.webRequest, container);
assertEquals(command, container.getModel().get(commandName));
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + commandName;
assertSame(dataBinder.getBindingResult(), container.getModel().get(bindingResultKey));
assertEquals(2, container.getModel().size());
}
@Test
public void updateModelSessionAttributesSaved() throws Exception {
String attributeName = "sessionAttr";
String attribute = "value";
ModelAndViewContainer container = new ModelAndViewContainer();
container.addAttribute(attributeName, attribute);
WebDataBinder dataBinder = new WebDataBinder(attribute, attributeName);
WebDataBinderFactory binderFactory = mock(WebDataBinderFactory.class);
given(binderFactory.createBinder(this.webRequest, attribute, attributeName)).willReturn(dataBinder);
ModelFactory modelFactory = new ModelFactory(null, binderFactory, this.attributeHandler);
modelFactory.updateModel(this.webRequest, container);
assertEquals(attribute, container.getModel().get(attributeName));
assertEquals(attribute, this.attributeStore.retrieveAttribute(this.webRequest, attributeName));
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
HttpMethod httpMethod = inputMessage.getMethod();
switch (httpMethod) {
case GET:
case HEAD:
return bindData(parameter, mavContainer, webRequest, binderFactory);
case POST:
case PUT:
case PATCH:
case DELETE:
case OPTIONS:
return convertBody(parameter, mavContainer, webRequest, binderFactory);
default:
return null;
}
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
RestResponse restResponse = null;
if (returnValue instanceof RestResponse) {
restResponse = (RestResponse) returnValue;
} else {
restResponse = new RestResponse(returnValue);
}
delegate.handleReturnValue(restResponse, returnType, mavContainer, webRequest);
}
@Override
public AccountAccessToken resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
String token = webRequest.getHeader(AccountAccessToken.HEADER_KEY);
// we only verify in memory for all request http method
// service layer should decide check database if mutation is critical
return accountService.tryDecodeAccessToken(token).orElseThrow(AccessDeniedException::new);
}
@Override
public Object resolveArgument( MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory ) throws Exception
{
String requestURI = ((HttpServletRequest) webRequest.getNativeRequest()).getRequestURI();
Matcher matcher = API_VERSION_PATTERN.matcher( requestURI );
if ( matcher.find() )
{
Integer version = Integer.valueOf( matcher.group( "version" ) );
return DhisApiVersion.getVersion( version );
}
return DhisApiVersion.DEFAULT;
}