Java项目跨域问题解决方案总结

做过跨系统的一般都会遇到跨域获取数据的问题,本人也是遇到了很多次。今天就来罗列一下解决跨域的几种解决方式和具体的方法。


1.在控制层(Controller)方法中加入一行

response.setHeader("Access-Control-Allow-Origin""*");

代表当前接口返回的数据支持跨域,*代表所有域名访问方都可以获取数据,也可以指定具体域名。

这种方式比较不友好,每个方法都要加一行代码。

2.Jsonp方式,比较常用的一种方法。ajax请求的时候为jsonp方式,增加callback参数。此方法只支持GET方式请求。

首先添加一个类集成MappingJackson2HttpMessageConverter 并复写writeInternal方法,添加jsonp返回支持。

代码如下:


import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonProcessingException;

public class CallbackMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {


// 做jsonp的支持的标识,在请求参数中加该参数
private String callbackName;


@Override
protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
// 从threadLocal中获取当前的Request对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String callbackParam = request.getParameter(callbackName);
if(StringUtils.isEmpty(callbackParam)){
// 没有找到callback参数,直接返回json数据
super.writeInternal(object, outputMessage);
}else{
JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
try {
String result =callbackParam+"("+super.getObjectMapper().writeValueAsString(object)+");";
IOUtils.write(result, outputMessage.getBody(),encoding.getJavaName());
}
catch (JsonProcessingException ex) {
throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
}
}

}


public String getCallbackName() {
return callbackName;
}


public void setCallbackName(String callbackName) {
this.callbackName = callbackName;
}


}


然后在mvc配置文件中加入:

<!-- MVC注解驱动 -->
<mvc:annotation-driven>
<!-- 采用自定义方案 -->
<mvc:message-converters>
<!-- 定义文本转化器 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg index="0" value="UTF-8"/>
</bean>
<!-- 定义json转化器,支持json跨域 -->
<bean class="xxx.util.spring.exetend.converter.json.CallbackMappingJackson2HttpMessageConverter">
<!-- 跨域请求中的请求参数名 -->
<property name="callbackName" value="callback"></property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

如果有多个message-converters需要写在一个annotation-driven里面,否则后面的无法生效。

配置完成后,页面获取数据添加callback参数就会走跨域的方法,不加就走正常流程。(ajax指定jsonp类型会自动追加callback参数)

3.注解方式解决跨域问题。

在Controller中加入@CrossOrigin注解。

@CrossOrigin(origins = "*", maxAge = 3600,methods={RequestMethod.POST})

跟第一种方法一样origins可以指定具体的域名,也可以指定请求方法,这个方法是整个Controller类全局的,会覆盖掉方法中指定的请求方法。

并且methods必须指定,不然会报错。

个人比较推荐这种方式。



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

新增springboot跨域解决方案,加入下面代码

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许cookies跨域
        config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
        config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
        config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
        config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

即可解决

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值