网站的导航栏设计文本,怎么做网页作业,景德镇建设企业网站,网站下载地址input发送a.jaxJava EE REST应用程序在开箱即用的开发机器上通常可以很好地运行#xff0c;在该机器上#xff0c;所有服务器端资源和客户端UI都指向“ localhost”或127.0.0.1。 但是#xff0c;当涉及跨域部署时#xff08;当REST客户端不再与托管REST API的服务器位于同… input发送a.jax Java EE REST应用程序在开箱即用的开发机器上通常可以很好地运行在该机器上所有服务器端资源和客户端UI都指向“ localhost”或127.0.0.1。 但是当涉及跨域部署时当REST客户端不再与托管REST API的服务器位于同一域时则需要一些解决方法。 本文是关于Java EE 7 / JAX-RS 2.0 REST API时如何使跨域或更广称为跨域资源共享又称为CORS的。 本文无意讨论有关浏览器和其他与安全性相关的机制您可能会在其他网站上找到它。 但是我们真正想要在这里实现的是再次使事情尽快运作。 问题是什么 演示Java EE 7JAX-RS 2.0REST服务 在本文中我将仅为演示目的而编写一个基于Java EE 7 JAX-RS 2.0的简单REST Web服务和客户端。 在这里我将定义一个接口以REST服务的url路径以及为HTTP响应接受的HTTP方法和MIME Type对其进行注释。 RESTCorsDemoResourceProxy.java的代码 package com.developerscrappad.intf;import java.io.Serializable;
import javax.ejb.Local;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;Local
Path( rest-cors-demo )
public interface RESTCorsDemoResourceProxy extends Serializable {GETPath( get-method )Produces( MediaType.APPLICATION_JSON )public Response getMethod();PUTPath( put-method )Produces( MediaType.APPLICATION_JSON )public Response putMethod();POSTPath( post-method )Produces( MediaType.APPLICATION_JSON )public Response postMethod();DELETEPath( delete-method )Produces( MediaType.APPLICATION_JSON )public Response deleteMethod();
} RESTCorsDemoResource.java的代码 package com.developerscrappad.business;import com.developerscrappad.intf.RESTCorsDemoResourceProxy;
import javax.ejb.Stateless;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.core.Response;Stateless( name RESTCorsDemoResource, mappedName ejb/RESTCorsDemoResource )
public class RESTCorsDemoResource implements RESTCorsDemoResourceProxy {Overridepublic Response getMethod() {JsonObjectBuilder jsonObjBuilder Json.createObjectBuilder();jsonObjBuilder.add( message, get method ok );JsonObject jsonObj jsonObjBuilder.build();return Response.status( Response.Status.OK ).entity( jsonObj.toString() ).build();}Overridepublic Response putMethod() {JsonObjectBuilder jsonObjBuilder Json.createObjectBuilder();jsonObjBuilder.add( message, get method ok );JsonObject jsonObj jsonObjBuilder.build();return Response.status( Response.Status.ACCEPTED ).entity( jsonObj.toString() ).build();}Overridepublic Response postMethod() {JsonObjectBuilder jsonObjBuilder Json.createObjectBuilder();jsonObjBuilder.add( message, post method ok );JsonObject jsonObj jsonObjBuilder.build();return Response.status( Response.Status.CREATED ).entity( jsonObj.toString() ).build();}Overridepublic Response deleteMethod() {JsonObjectBuilder jsonObjBuilder Json.createObjectBuilder();jsonObjBuilder.add( message, delete method ok );JsonObject jsonObj jsonObjBuilder.build();return Response.status( Response.Status.ACCEPTED ).entity( jsonObj.toString() ).build();}
} RESTCorsDemoResource中的代码简单明了但是请记住这只是一个演示应用程序在其业务逻辑中没有有效的目的。 RESTCorsDemoResource类实现在接口RESTCorsDemoResourceProxy中定义的方法签名。 它有几种方法可以通过特定的HTTP方法例如GETPUTPOST和DELETE处理传入的HTTP请求并且在方法结束时在完成该过程后将返回一条简单的JSON消息。 不要忘了下面的web.xml 当路径检测到“ / rest-api / * ”例如http// hostport时该web.xml会告诉应用服务器将其视为任何传入HTTP请求的REST API调用。 / AppName / rest-api / get-method /。 web.xml中的内容 javax.ws.rs.core.Application1javax.ws.rs.core.Application/rest-api/*部署方式 让我们将以上内容打包到一个名为RESTCorsDemo.war的war文件中并将其部署到与Java EE 7兼容的应用服务器中。 在我这方面我正在使用默认设置在Glassfish 4.0上运行此程序该默认设置位于具有公共域的计算机上developerscrappad.com 部署后REST服务的URL应如下所示 方法 REST URL RESTCorsDemoResourceProxy.getMethod http://developerscrappad.com/RESTCorsDemo/rest-api/rest-cors-demo/get-method/ RESTCorsDemoResourceProxy.postMethod http://developerscrappad.com/RESTCorsDemo/rest-api/rest-cors-demo/post-method/ RESTCorsDemoResourceProxy.putMethod http://developerscrappad.com/RESTCorsDemo/rest-api/rest-cors-demo/put-method/ RESTCorsDemoResourceProxy.deleteMethod http://developerscrappad.com/RESTCorsDemo/rest-api/rest-cors-demo/delete-method/ HTML REST客户端 在本地计算机上我将创建一个简单HTML页面以通过以下方式调用已部署的REST服务器资源 rest-test.html的代码 !DOCTYPE html
htmlheadtitleREST Tester/titlemeta charsetUTF-8/headbodydiv idlogMsgDiv/divscript srchttp://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js/scriptscript typetext/javascriptvar $ jQuery.noConflict();$.ajax( {cache: false,crossDomain: true,dataType: json,url: http://developerscrappad.com:8080/RESTCorsDemo/rest-api/rest-cors-demo/get-method/,type: GET,success: function( jsonObj, textStatus, xhr ) {var htmlContent $( #logMsgDiv ).html( ) p jsonObj.message /p;$( #logMsgDiv ).html( htmlContent );},error: function( xhr, textStatus, errorThrown ) {console.log( HTTP Status: xhr.status );console.log( Error textStatus: textStatus );console.log( Error thrown: errorThrown );}} );$.ajax( {cache: false,crossDomain: true,dataType: json,url: http://developerscrappad.com:8080/RESTCorsDemo/rest-api/rest-cors-demo/post-method/,type: POST,success: function( jsonObj, textStatus, xhr ) {var htmlContent $( #logMsgDiv ).html( ) p jsonObj.message /p;$( #logMsgDiv ).html( htmlContent );},error: function( xhr, textStatus, errorThrown ) {console.log( HTTP Status: xhr.status );console.log( Error textStatus: textStatus );console.log( Error thrown: errorThrown );}} );$.ajax( {cache: false,crossDomain: true,dataType: json,url: http://developerscrappad.com:8080/RESTCorsDemo/rest-api/rest-cors-demo/put-method/,type: PUT,success: function( jsonObj, textStatus, xhr ) {var htmlContent $( #logMsgDiv ).html( ) p jsonObj.message /p;$( #logMsgDiv ).html( htmlContent );},error: function( xhr, textStatus, errorThrown ) {console.log( HTTP Status: xhr.status );console.log( Error textStatus: textStatus );console.log( Error thrown: errorThrown );}} );$.ajax( {cache: false,crossDomain: true,dataType: json,url: http://developerscrappad.com:8080/RESTCorsDemo/rest-api/rest-cors-demo/delete-method/,type: DELETE,success: function( jsonObj, textStatus, xhr ) {var htmlContent $( #logMsgDiv ).html( ) p jsonObj.message /p;$( #logMsgDiv ).html( htmlContent );},error: function( xhr, textStatus, errorThrown ) {console.log( HTTP Status: xhr.status );console.log( Error textStatus: textStatus );console.log( Error thrown: errorThrown );}} );/script/body
/html 在这里我将jQuery的ajax对象用于带有已定义选项的REST Services调用。 rest-test.html的目的是使用适当的HTTP方法调用REST服务URL并获取响应作为JSON结果以供以后处理。 我不会在这里详细介绍但是如果您想了解更多有关$ .ajax调用选项的信息可以访问jQuery的文档站点 。 当我们运行rest-test.html时会发生什么 当我在Firefox浏览器上运行rest-test.html文件时配备了Firebug插件 以下是我得到的屏幕截图。 屏幕快照Firebug控制台选项卡结果 屏幕截图Firebug的“ Net”选项卡结果 如您所见当我在控制台选项卡上选中时“ / rest-api / rest-cors-demo / get-method / ”和“ / rest-api / rest-cors-demo / post-method / ”返回了正确的HTTP状态但我可以绝对确定该方法未在远程Glassfish应用服务器上执行REST服务调用只是被绕过在rest-test.html客户端上它直接进入了$ .ajax错误回调。 当我如图所示检查Firebug网络选项卡时“ / rest-api / rest-cors-demo / put-method / ”和“ / rest-api / rest-cors-demo / delete-method / ”如何处理在其中一个屏幕截图中浏览器通过触发OPTIONS作为HTTP方法而不是PUT和DELETE发送了预检请求。 这种现象与服务器端和浏览器的安全有关。 我在页面底部还编译了与此相关的其他一些网站。 如何使CORS在Java EE 7 / JAX-RS 2.0通过拦截器中工作 为了在客户端和服务器端REST资源上进行跨域调用或简称为CORS我创建了两个JAX-RS 2.0拦截器类一个实现了ContainerRequestFilter 另一个实现了ContainerResponseFilter 。 ContainerResponseFilter中的其他HTTP标头 浏览器将需要一些其他的HTTP标头来响应它以进一步验证服务器端资源是否允许跨域/跨域资源共享以及它允许的安全级别或限制级别。 这些标头在启用CORS时开箱即用。 Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, DELETE, PUT 这些额外的HTTP标头集可以通过将其包含在实现ContainerResponseFilter的类中而包含在返回到浏览器时的HTTP响应中。 **但请注意拥有“访问控制允许来源*”将允许接受所有呼叫而与客户端的位置无关。 有多种方法可以进一步限制此限制因为您只希望服务器端仅允许来自特定域的REST服务调用。 请查看页面底部的相关文章。 RESTCorsDemoResponseFilter.java的代码 package com.developerscrappad.filter;import java.io.IOException;
import java.util.logging.Logger;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.ext.Provider;Provider
PreMatching
public class RESTCorsDemoResponseFilter implements ContainerResponseFilter {private final static Logger log Logger.getLogger( RESTCorsDemoResponseFilter.class.getName() );Overridepublic void filter( ContainerRequestContext requestCtx, ContainerResponseContext responseCtx ) throws IOException {log.info( Executing REST response filter );responseCtx.getHeaders().add( Access-Control-Allow-Origin, * );responseCtx.getHeaders().add( Access-Control-Allow-Credentials, true );responseCtx.getHeaders().add( Access-Control-Allow-Methods, GET, POST, DELETE, PUT );}
}处理浏览器预检请求HTTP方法选项 实现ContainerResponseFilter的RESTCorsDemoResponseFilter类仅解决了部分问题。 我们仍然必须处理浏览器对PUT和DELETE HTTP方法的飞行前请求。 大多数流行的浏览器的基础飞行前请求机制都以某种方式工作即它们使用OPTIONS作为HTTP方法发送一个请求只是为了测试水域。 如果服务器端资源确认请求的路径URL并允许接受PUT或DELETE HTTP方法进行处理则服务器端通常将必须发送HTTP Status 200OK响应或任何20x HTTP Status返回到浏览器然后浏览器将实际请求作为HTTP方法PUT或DELETE发送给浏览器。 但是此机制必须由开发人员手动实现。 因此我以RESTCorsDemoRequestFilter的名称实现了一个新类 该类实现了以下针对此机制显示的ContainerRequestFilter 。 RESTCorsDemoRequestFilter.java的代码 package com.developerscrappad.filter;import java.io.IOException;
import java.util.logging.Logger;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;Provider
PreMatching
public class RESTCorsDemoRequestFilter implements ContainerRequestFilter {private final static Logger log Logger.getLogger( RESTCorsDemoRequestFilter.class.getName() );Overridepublic void filter( ContainerRequestContext requestCtx ) throws IOException {log.info( Executing REST request filter );// When HttpMethod comes as OPTIONS, just acknowledge that it accepts...if ( requestCtx.getRequest().getMethod().equals( OPTIONS ) ) {log.info( HTTP Method (OPTIONS) - Detected! );// Just send a OK signal back to the browserrequestCtx.abortWith( Response.status( Response.Status.OK ).build() );}}
}结果 之后 RESTCorsDemoResponseFilter和RESTCorsDemoRequestFilter包含在应用程序中并进行部署。 然后我再次在浏览器上重新运行rest-test.html 。 结果JAX-RS 2.0应用程序很好地处理了来自不同位置的具有不同HTTP方法GETPOSTPUT和DELETE的所有HTTP请求。 下面的屏幕截图是我的浏览器成功执行的HTTP请求。 Firebug控制台和NET Tab的这些结果是预期的 屏幕快照Firebug控制台选项卡 屏幕截图Firebug的“ Net”选项卡 最后的话 在拦截诸如启用CORS之类的方案的REST相关请求和响应时JAX-RS 2.0拦截器非常方便。 如果您正在为Java项目使用REST库的特定实现例如Jersey或RESTEasy 请检查如何具体实现请求和响应拦截器应用上述技术您应该可以获得相同的结果。 相同的原理几乎相同。 好吧希望本文能帮助您解决Java EE 7 / JAX-RS 2.0 REST项目上的跨域或CORS问题。 感谢您的阅读。 相关文章 http://en.wikipedia.org/wiki/Cross-origin_resource_sharing http://www.html5rocks.com/zh-CN/tutorials/cors/ http://www.w3.org/TR/cors/ https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS 翻译自: https://www.javacodegeeks.com/2014/11/java-ee-7-jax-rs-2-0-cors-on-rest.htmlinput发送a.jax