通過追蹤代碼發(fā)現(xiàn)play框架在收到http請(qǐng)求后將HTTP請(qǐng)求在pipeline中被交給了PlayHandler來處理
在PlayHandler的messageReceived方法中有如下代碼片段:
Http.Request.current.set(new Http.Request());
finalResponse response =new Response();
Http.Response.current.set(response);
final Request request = parseRequest(ctx, nettyRequest, messageEvent);
可以看到request請(qǐng)求被獲取到并放入了ThreadLocal中
往下追蹤我們可以看到play框架調(diào)用了一組插件來處理當(dāng)前請(qǐng)求,每個(gè)請(qǐng)求都會(huì)調(diào)用插件的rawInvocation方法
boolean raw = Play.pluginCollection.rawInvocation(request, response);
我們可以在這個(gè)方法里面給response注入
Access-Control-Allow-Origin:*
那么自實(shí)現(xiàn)一個(gè)插件:
CorsPlugin:
importplay.PlayPlugin;
importplay.mvc.Http;
/**
* Created by yyp on 2017/7/5.
*/
public class CorsPlugin extends PlayPlugin {
public CorsPlugin() {
}
@Override
public boolean rawInvocation(Http.Request request, Http.Response response) throws Exception {
//獲取請(qǐng)求頭中的請(qǐng)求類型
if(request.headers.containsKey("access-control-request-method")) {
//注入請(qǐng)求類型到requst的method中// 在跨域請(qǐng)求中play框架不會(huì)自轉(zhuǎn)換請(qǐng)求類型所以需要手動(dòng)注入
request.method= request.headers.get("access-control-request-method").value();
}
Http.Response.current().setHeader("Access-Control-Allow-Origin","*");
if( request.headers.containsKey("access-control-request-headers")) {
Http.Response.current().setHeader("Access-Control-Allow-Headers",request.headers.get("access-control-request-headers").value());
}
return super.rawInvocation(request, response);
}
}
將插件注入play框架中
在conf中新建文件play.plugins ?在里面寫入
800:com.power.util.CorsPlugin
其中800指的是插件的執(zhí)行順序,play會(huì)掃描classpath下所有的play.plugins文件來加載插件
如下:
play框架自帶的插件文件如下:
0:play.CorePlugin
1:play.ConfigurationChangeWatcherPlugin
100:play.data.parsing.TempFilePlugin
200:play.data.validation.ValidationPlugin
300:play.db.DBPlugin
400:play.db.jpa.JPAPlugin
450:play.db.Evolutions
500:play.i18n.MessagesPlugin
600:play.libs.WS
700:play.jobs.JobsPlugin
100000:play.plugins.ConfigurablePluginDisablingPlugin
自此解決play框架跨域問題