• 实现跨域请求jsonp方式


    原理:http://madong.net.cn/index.php/2012/12/368/

    调用端:

    $.getJSON("http://192.168.220.85:8001/esb/autocredit/test?callback=?",function(data){
    alert(data);
    });

    服务端:(基于spring mvc  @RestController 或 @ResponseBody注解)

    更改源码:ServletInvocableHandlerMethod.java

    主要添加:

    ---------------------------------------------

    String parameter = webRequest.getParameter("callback");
    if (parameter != null) {
    returnValue = parameter + "(" + returnValue.toString() + ")";
    }

    ---------------------------------------------

    /*
    * Copyright 2002-2012 the original author or authors.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    package org.springframework.web.servlet.mvc.method.annotation;

    import java.io.IOException;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    import java.util.concurrent.Callable;

    import org.springframework.http.HttpStatus;
    import org.springframework.util.ClassUtils;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.ResponseStatus;
    import org.springframework.web.context.request.ServletWebRequest;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
    import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
    import org.springframework.web.method.support.InvocableHandlerMethod;
    import org.springframework.web.method.support.ModelAndViewContainer;
    import org.springframework.web.servlet.View;
    import org.springframework.web.util.NestedServletException;

    /**
    * Extends {@link InvocableHandlerMethod} with the ability to handle return
    * values through a registered {@link HandlerMethodReturnValueHandler} and also
    * supports setting the response status based on a method-level
    * {@code @ResponseStatus} annotation.
    *
    * <p>
    * A {@code null} return value (including void) may be interpreted as the end of
    * request processing in combination with a {@code @ResponseStatus} annotation,
    * a not-modified check condition (see
    * {@link ServletWebRequest#checkNotModified(long)}), or a method argument that
    * provides access to the response stream.
    *
    * @author Rossen Stoyanchev
    * @since 3.1
    */
    public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {

    private HttpStatus responseStatus;

    private String responseReason;

    private HandlerMethodReturnValueHandlerComposite returnValueHandlers;

    /**
    * Creates an instance from the given handler and method.
    */
    public ServletInvocableHandlerMethod(Object handler, Method method) {
    super(handler, method);
    initResponseStatus();
    }

    /**
    * Create an instance from a {@code HandlerMethod}.
    */
    public ServletInvocableHandlerMethod(HandlerMethod handlerMethod) {
    super(handlerMethod);
    initResponseStatus();
    }

    private void initResponseStatus() {
    ResponseStatus annot = getMethodAnnotation(ResponseStatus.class);
    if (annot != null) {
    this.responseStatus = annot.value();
    this.responseReason = annot.reason();
    }
    }

    /**
    * Register {@link HandlerMethodReturnValueHandler} instances to use to
    * handle return values.
    */
    public void setHandlerMethodReturnValueHandlers(HandlerMethodReturnValueHandlerComposite returnValueHandlers) {
    this.returnValueHandlers = returnValueHandlers;
    }

    /**
    * Invokes the method and handles the return value through a registered
    * {@link HandlerMethodReturnValueHandler}.
    *
    * @param webRequest
    * the current request
    * @param mavContainer
    * the ModelAndViewContainer for this request
    * @param providedArgs
    * "given" arguments matched by type, not resolved
    */
    public final void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

    Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);

    // 为实现跨域请求 添加实现 add by x
    String parameter = webRequest.getParameter("callback");
    if (parameter != null) {
    returnValue = parameter + "(" + returnValue.toString() + ")";
    }
    // 为实现跨域请求 添加实现 add by x

    setResponseStatus(webRequest);

    if (returnValue == null) {
    if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
    mavContainer.setRequestHandled(true);
    return;
    }
    } else if (StringUtils.hasText(this.responseReason)) {
    mavContainer.setRequestHandled(true);
    return;
    }

    mavContainer.setRequestHandled(false);

    try {
    this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
    } catch (Exception ex) {
    if (logger.isTraceEnabled()) {
    logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
    }
    throw ex;
    }
    }

    /**
    * Set the response status according to the {@link ResponseStatus}
    * annotation.
    */
    private void setResponseStatus(ServletWebRequest webRequest) throws IOException {
    if (this.responseStatus == null) {
    return;
    }

    if (StringUtils.hasText(this.responseReason)) {
    webRequest.getResponse().sendError(this.responseStatus.value(), this.responseReason);
    } else {
    webRequest.getResponse().setStatus(this.responseStatus.value());
    }

    // to be picked up by the RedirectView
    webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, this.responseStatus);
    }

    /**
    * Does the given request qualify as "not modified"?
    *
    * @see ServletWebRequest#checkNotModified(long)
    * @see ServletWebRequest#checkNotModified(String)
    */
    private boolean isRequestNotModified(ServletWebRequest webRequest) {
    return webRequest.isNotModified();
    }

    /**
    * Does this method have the response status instruction?
    */
    private boolean hasResponseStatus() {
    return responseStatus != null;
    }

    private String getReturnValueHandlingErrorMessage(String message, Object returnValue) {
    StringBuilder sb = new StringBuilder(message);
    if (returnValue != null) {
    sb.append(" [type=" + returnValue.getClass().getName() + "] ");
    }
    sb.append("[value=" + returnValue + "]");
    return getDetailedErrorMessage(sb.toString());
    }

    /**
    * Create a ServletInvocableHandlerMethod that will return the given value
    * from an async operation instead of invoking the controller method again.
    * The async result value is then either processed as if the controller
    * method returned it or an exception is raised if the async result value
    * itself is an Exception.
    */
    ServletInvocableHandlerMethod wrapConcurrentResult(final Object result) {

    return new CallableHandlerMethod(new Callable<Object>() {

    @Override
    public Object call() throws Exception {
    if (result instanceof Exception) {
    throw (Exception) result;
    } else if (result instanceof Throwable) {
    throw new NestedServletException("Async processing failed", (Throwable) result);
    }
    return result;
    }
    });
    }

    /**
    * A sub-class of {@link HandlerMethod} that invokes the given
    * {@link Callable} instead of the target controller method. This is useful
    * for resuming processing with the result of an async operation. The goal
    * is to process the value returned from the Callable as if it was returned
    * by the target controller method, i.e. taking into consideration both
    * method and type-level controller annotations (e.g. {@code @ResponseBody},
    * {@code @ResponseStatus}, etc).
    */
    private class CallableHandlerMethod extends ServletInvocableHandlerMethod {

    public CallableHandlerMethod(Callable<?> callable) {
    super(callable, ClassUtils.getMethod(callable.getClass(), "call"));
    this.setHandlerMethodReturnValueHandlers(ServletInvocableHandlerMethod.this.returnValueHandlers);
    }

    /**
    * Bridge to type-level annotations of the target controller method.
    */
    @Override
    public Class<?> getBeanType() {
    return ServletInvocableHandlerMethod.this.getBeanType();
    }

    /**
    * Bridge to method-level annotations of the target controller method.
    */
    @Override
    public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
    return ServletInvocableHandlerMethod.this.getMethodAnnotation(annotationType);
    }
    }

    }

  • 相关阅读:
    Spring ApplicationListener 理解
    Tomcat 的context.xml说明、Context标签讲解
    IntrospectorCleanupListener作用
    Dubbo 和 Spring Cloud微服务架构 比较及相关差异
    ZooKeeper原理 --------这可能是把ZooKeeper概念讲的最清楚的一篇文章
    Dubbo 入门
    makefile的调试器remake
    linux下的nmap工具能干什么?
    makefile中的patsubst函数有何作用?
    openwrt为何需要refresh新增的补丁?
  • 原文地址:https://www.cnblogs.com/adolfmc/p/5130434.html
Copyright © 2020-2023  润新知