input发送a.jax

带有JAX-RS 2.0的Java EE 7带来了几个有用的功能,这些功能进一步简化了开发并导致创建了更加复杂但精简的Java SE / EE RESTful应用程序。 亚当·比恩(Adam Bien)向我们介绍了Java EE 7的主要功能之一。 经Oracle技术网(Oracle公司)许可转载。

样例代码

大多数需要远程API和自由选择的Java EE 6应用程序都使用或多或少具有RESTful风格的JAX-RS 1.0规范。 带有JAX-RS 2.0的Java EE 7带来了几个有用的功能,这些功能进一步简化了开发并导致创建了更加复杂但精简的Java SE / EE RESTful应用程序。

烤房

Roast House是一个Java友好但简单的JAX-RS 2.0示例,它管理和烘焙一些咖啡豆。 CoffeeBeansResource本身表示为CoffeeBeansResource 。 URI "coffeebeans"唯一地标识CoffeeBeansResource (请参见清单1 )。

清单1

//...
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.container.ResourceContext;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
@ApplicationScoped
@Path("coffeebeans")
public class CoffeeBeansResource {@ContextResourceContext rc;Map<String, Bean> bc;@PostConstructpublic void init() {this.bc = new ConcurrentHashMap<>();}@GETpublic Collection<Bean> allBeans() {return bc.values();}@GET@Path("{id}")public Bean bean(@PathParam("id") String id) {return bc.get(id);}@POSTpublic Response add(Bean bean) {if (bean != null) {bc.put(bean.getName(), bean);}final URI id = URI.create(bean.getName());return Response.created(id).build();}@DELETE@Path("{id}")public void remove(@PathParam("id") String id) {bc.remove(id);}@Path("/roaster/{id}")public RoasterResource roaster(){return this.rc.initResource(new RoasterResource());}
}

与以前的JAX-RS规范一样,资源可以是@Singleton@Stateless EJB。 此外,所有根资源,提供程序和Application子类都可以部署为托管或CDI托管Bean。 在所有带有@Provider注释的扩展中,注入功能也可用,从而简化了与现有代码的集成。 还可以使用ResourceContext将特定于JAX-RS的组件注入子ResourceContext

清单2

@ContextResourceContext rc;@Path("/roaster/{id}")public RoasterResource roaster(){return this.rc.initResource(new RoasterResource());}

有趣的是, javax.ws.rs.container.ResourceContext不仅允许您将JAX-RS信息注入到现有实例中,而且还允许您使用ResourceContext#getResource(Class<T> resourceClass)方法访问资源类。 传递给ResourceContext#initResource方法的实例的注入点由JAX-RS运行时使用当前上下文中的值进行设置。 RoasterResource类中的String id字段(如清单3所示)接收父级资源的path参数的值:

清单3

public class RoasterResource {@PathParam("id")private String id;@POSTpublic void roast(@Suspended AsyncResponse ar, Bean bean) {try {Thread.sleep(2000);} catch (InterruptedException ex) {}bean.setType(RoastType.DARK);bean.setName(id);bean.setBlend(bean.getBlend() + ": The dark side of the bean");Response response = Response.ok(bean).header("x-roast-id", id).build();ar.resume(response);}
}

参数javax.ws.rs.container.AsyncResponse与Servlet 3.0 javax.servlet.AsyncContext类相似,并允许异步请求执行。 在上面的示例中,请求在处理期间被挂起,并且通过调用方法AsyncResponse#resume将响应推送到客户端。 方法roast仍然是同步执行的,因此异步执行根本不会带来任何异步行为。 但是,EJB的@javax.ejb.Asynchronous批注和@Suspended AsyncResponse可以异步执行业务逻辑,并最终通知感兴趣的客户端。 任何JAX-RS根资源都可以使用@Stateless@Singleton注释进行注释,并且实际上可以用作EJB(参见清单4 ):

清单4

import javax.ejb.Asynchronous;
import javax.ejb.Singleton;@Stateless
@Path("roaster")
public class RoasterResource {@POST@Asynchronouspublic void roast(@Suspended AsyncResponse ar, Bean bean) {//heavy liftingResponse response = Response.ok(bean).build();ar.resume(response);}
}

带有@Suspended AsyncResponse参数的@Asynchronous资源方法以“ @Suspended AsyncResponse方式执行。 尽管可以立即释放请求处理线程,但AsyncResponse仍然为客户端提供了方便的句柄。 完成耗时的工作后,可以方便地将结果推回给客户。 通常,您希望将特定于JAX-RS的行为与实际业务逻辑分开。 可以轻松地将所有业务逻辑提取到专用的边界EJB中,但是CDI事件甚至更适合于覆盖即发即弃的情况。 定制事件类RoastRequest携带有效负载( Bean类)作为处理输入,并携带AsyncResponse作为结果提交(请参见清单5 ):

清单5

public class RoastRequest {private Bean bean;private AsyncResponse ar;public RoastRequest(Bean bean, AsyncResponse ar) {this.bean = bean;this.ar = ar;}public Bean getBean() {return bean;}public void sendMessage(String result) {Response response = Response.ok(result).build();ar.resume(response);}public void errorHappened(Exception ex) {ar.resume(ex);}
}

CDI事件不仅使业务逻辑与JAX-RS API脱钩,而且还大大简化了JAX-RS代码(请参见清单6)

清单6

public class RoasterResource {@InjectEvent<RoastRequest> roastListeners;@POSTpublic void roast(@Suspended AsyncResponse ar, Bean bean) {roastListeners.fire(new RoastRequest(bean, ar));}
}

任何CDI管理的bean或EJB都可以以发布-订阅的方式接收RoastRequest ,并使用简单的观察者方法: void onRoastRequest(@Observes RoastRequest request){}同步或异步处理有效负载。

通过AsyncResponse类,JAX-RS规范引入了一种将信息实时推送到HTTP的简便方法。 从客户端的角度来看,服务器上的异步请求仍然处于阻塞状态,因此是同步的。 从REST设计的角度来看,所有长时间运行的任务都应立即返回HTTP状态代码202,以及有关在处理完成后如何获取结果的其他信息。

方面的回归

流行的REST API通常要求其客户端计算消息的指纹并将其与请求一起发送。 在服务器端,计算指纹并将其与附加信息进行比较。 如果两者都不匹配,则消息将被拒绝。 随着JAX-RS的到来和javax.ws.rs.ext.ReaderInterceptor javax.ws.rs.ext.WriterInterceptor的引入,可以在服务器端甚至在客户端拦截流量。 服务器上ReaderInterceptor接口的实现包装了MessageBodyReader#readFrom并在实际序列化之前执行。

PayloadVerifier从标头中获取签名,从流中计算指纹,并最终调用ReaderInterceptorContext#proceed方法,该方法将调用链中的下一个拦截器或MessageBodyReader实例(请参见清单7 )。

清单7

public class PayloadVerifier implements ReaderInterceptor{public static final String SIGNATURE_HEADER = "x-signature";@Overridepublic Object aroundReadFrom(ReaderInterceptorContext ric) throws IOException,
WebApplicationException {MultivaluedMap<String, String> headers = ric.getHeaders();String headerSignagure = headers.getFirst(SIGNATURE_HEADER);InputStream inputStream = ric.getInputStream();byte[] content = fetchBytes(inputStream);String payload = computeFingerprint(content);if (!payload.equals(headerSignagure)) {Response response = Response.status(Response.Status.BAD_REQUEST).header(SIGNATURE_HEADER, "Modified content").build();throw new WebApplicationException(response);}ByteArrayInputStream buffer = new ByteArrayInputStream(content);ric.setInputStream(buffer);return ric.proceed();}//...
}

修改后的内容会导致不同的指纹,并导致使用BAD_REQUEST(400)响应代码引发WebApplicationException

指纹或传出请求的所有计算都可以通过WriterInterceptor的实现轻松实现自动化。 WriterInterceptor的实现包装MessageBodyWriter#writeTo并在将实体序列化为流之前执行。 对于指纹计算,需要“在线”实体的最终表示形式,因此我们传递ByteArrayOutputStream作为缓冲区,调用WriterInterceptorContext#proceed()方法,获取原始内容并计算指纹。 参见清单8

清单8

public class PayloadVerifier implements WriterInterceptor {public static final String SIGNATURE_HEADER = "x-signature";@Overridepublic void aroundWriteTo(WriterInterceptorContext wic) throws IOException,
WebApplicationException {OutputStream oos = wic.getOutputStream();ByteArrayOutputStream baos = new ByteArrayOutputStream();wic.setOutputStream(baos);wic.proceed();baos.flush();byte[] content = baos.toByteArray();MultivaluedMap<String, Object> headers = wic.getHeaders();headers.add(SIGNATURE_HEADER, computeFingerprint(content));oos.write(content);}//...
}

最后,将计算出的签名作为标头添加到请求,将缓冲区写入原始流,然后将整个请求发送到客户端。 当然,单个类也可以同时实现两个接口:

清单9

import javax.ws.rs.ext.Provider;
@Provider
public class PayloadVerifier implements ReaderInterceptor, WriterInterceptor {
}

与以前的JAX-RS版本一样,将自动发现自定义扩展并将其注册为@Provider批注。 为了拦截MessageBodyWriterMessageBodyReader实例,只需使用@Provider批注对ReaderInterceptorWriterInterceptor的实现进行批注-无需其他配置或API调用。

请求拦截

ContainerRequestFilterContainerResponseFilter拦截整个请求,而不仅是读取和写入实体的过程。 这两个拦截器的功能远比记录原始javax.servlet.http.HttpServletRequest实例中包含的信息有用。 TrafficLogger类不仅能够记录HttpServletRequest包含的信息,而且还可以跟踪与匹配特定请求的资源有关的信息,如清单10所示。

清单10

@Provider
public class TrafficLogger implements ContainerRequestFilter, ContainerResponseFilter {//ContainerRequestFilterpublic void filter(ContainerRequestContext requestContext) throws IOException {log(requestContext);}//ContainerResponseFilterpublic void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {log(responseContext);}void log(ContainerRequestContext requestContext) {SecurityContext securityContext = requestContext.getSecurityContext();String authentication = securityContext.getAuthenticationScheme();Principal userPrincipal = securityContext.getUserPrincipal();UriInfo uriInfo = requestContext.getUriInfo();String method = requestContext.getMethod();List<Object> matchedResources = uriInfo.getMatchedResources();//...}void log(ContainerResponseContext responseContext) {MultivaluedMap<String, String> stringHeaders = responseContext.getStringHeaders();Object entity = responseContext.getEntity();//...}
}

因此,注册实施的ContainerResponseFilter得到的实例ContainerResponseContext并能够访问由服务器生成的数据。 状态代码和标头内容(例如Location标头)可轻松访问。 ContainerRequestContextContainerResponseContext是可变的类,可以通过过滤器进行修改。

在没有任何其他配置的情况下, ContainerRequestFilter在HTTP资源匹配阶段之后执行。 此时,不再可能修改传入的请求以自定义资源绑定。 如果您希望影响请求和资源之间的绑定,可以将ContainerRequestFilter配置为在资源绑定阶段之前执行。 任何使用javax.ws.rs.container.PreMatching注释注释的ContainerRequestFilter都会在资源绑定之前执行,因此可以对HTTP请求内容进行调整以进行所需的映射。 @PreMatching过滤器的常见用例是调整HTTP谓词以克服网络基础结构中的限制。 更多“神秘”的方法(例如PUTOPTIONSHEADDELETE可能会被防火墙过滤掉,或者某些HTTP客户端不支持。 @PreMatching ContainerRequestFilter实现可以从标头(例如,“ X-HTTP-Method-Override ”)中获取指示所需的HTTP动词的信息,并且可以将POST请求即时更改为PUT (请参见清单11 )。

清单11

@Provider
@PreMatching
public class HttpMethodOverrideEnabler implements ContainerRequestFilter {public void filter(ContainerRequestContext requestContext) throws IOException {String override = requestContext.getHeaders().getFirst("X-HTTP-Method-Override");if (override != null) {requestContext.setMethod(override);}}
}

组态

使用@Provider批注注册的所有拦截器和过滤器@Provider为所有资源全局启用。 在部署时,服务器会在部署单元中扫描@Provider批注,并在激活应用程序之前自动注册所有扩展。 所有扩展都可以打包到专用JAR中,并根据需要与WAR一起部署(在WEB-INF/lib文件夹中)。 JAX-RS运行时将扫描JAR并自动注册扩展。 自包含的JAR的直接部署很好,但是需要细粒度的扩展打包。 JAR中包含的所有扩展都将被立即激活。

JAX-RS引入了绑定注释,用于选择性装饰资源。 其机制类似于CDI限定词。 任何以meta-annotation javax.ws.rs.NameBinding表示的自定义注释都可以用于声明拦截点:

清单12

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Tracked {
}

通过在Application的类,方法甚至子类上应用相同的Tracked注释,可以有选择地激活用Tracked注释表示的所有拦截器或过滤器:

清单13

@Tracked
@Provider
public class TrafficLogger implements ContainerRequestFilter, ContainerResponseFilter {
}

可以将自定义NameBinding批注与相应的过滤器或拦截器打包在一起,并由应用程序开发人员有选择地应用于资源。 尽管注释驱动的方法显着提高了灵活性并允许使用较粗的插件程序包,但绑定仍然是静态的。 需要重新编译应用程序并有效地对其进行重新部署,以更改拦截器或过滤器链。

除了跨领域功能的全局和注释驱动配置之外,JAX-RS 2.0还引入了用于动态扩展注册的新API。 容器使用带有@Provider注释的javax.ws.rs.container.DynamicFeature接口的实现作为容器的钩子,用于动态注册拦截器和过滤器,而无需重新编译。 LoggerRegistration扩展通过查询是否存在预定义的系统属性来有条件地注册PayloadVerifier拦截器和TrafficLogger过滤器,如清单14所示:

清单14

@Provider
public class LoggerRegistration implements DynamicFeature {@Overridepublic void configure(ResourceInfo resourceInfo, FeatureContext context) {String debug = System.getProperty("jax-rs.traffic");if (debug != null) {context.register(new TrafficLogger());}String verification = System.getProperty("jax-rs.verification");if (verification != null) {context.register(new PayloadVerifier());}}
}

客户端

JAX-RS 1.1规范未涵盖该客户端。 尽管客户端REST API的专有实现(例如RESTEasy或Jersey)可以与任何HTTP资源进行通信(甚至无法使用Java EE进行通信),但是客户端代码直接取决于特定的实现。 JAX-RS 2.0引入了新的标准化客户端API。 使用标准的引导程序,可以替换服务提供商接口(SPI)。 该API很流畅,并且与大多数专有REST客户端实现类似(请参见清单15 )。

清单15

import java.util.Collection;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;public class CoffeeBeansResourceTest {Client client;WebTarget root;@Beforepublic void initClient() {this.client = ClientBuilder.newClient().register(PayloadVerifier.class);this.root = this.client.target("http://localhost:8080/roast-house/api/coffeebeans");}@Testpublic void crud() {Bean origin = new Bean("arabica", RoastType.DARK, "mexico");final String mediaType = MediaType.APPLICATION_XML;final Entity<Bean> entity = Entity.entity(origin, mediaType);Response response = this.root.request().post(entity, Response.class);assertThat(response.getStatus(), is(201));Bean result = this.root.path(origin.getName()).request(mediaType).get(Bean.class);assertThat(result, is(origin));Collection<Bean> allBeans = this.root.request().get(
new GenericType<Collection<Bean>>() {});assertThat(allBeans.size(), is(1));assertThat(allBeans, hasItem(origin));response = this.root.path(origin.getName()).request(mediaType).delete(Response.class);assertThat(response.getStatus(), is(204));response = this.root.path(origin.getName()).request(mediaType).get(Response.class);assertThat(response.getStatus(), is(204));}
//..
}

在上面的集成测试中,默认的Client实例是使用无参数的ClientFactory.newClient()方法获得的。 使用内部javax.ws.rs.ext.RuntimeDelegate抽象工厂对引导过程本身进行标准化。 可以将现有的RuntimeDelegate实例(例如通过依赖项注入框架)注入ClientFactory ,也可以通过在文件META-INF/services/javax.ws.rs.ext.RuntimeDelegate${java.home}/lib/jaxrs.properties并最终通过搜索javax.ws.rs.ext.RuntimeDelegate系统属性。 通过失败的发现,尝试初始化默认(Jersey)实现。

javax.ws.rs.client.Client的主要目的是能够流畅地访问javax.ws.rs.client.WebTargetjavax.ws.rs.client.Invocation实例。 WebTarget代表JAX-RS资源,而Invocation是等待提交的即用型请求。 WebTarget也是一个Invocation工厂。

在方法CoffeBeansResourceTest#crud()Bean对象在客户端和服务器之间来回传递。 通过选择MediaType.APPLICATION_XML ,只需要几个JAXB批注即可发送和接收在XML文档中序列化的DTO:

清单16

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Bean {private String name;private RoastType type;private String blend;}

类名和属性的名称必须匹配才能成功与服务器的表示进行封送处理,但是DTO不必与二进制兼容。 在上面的示例中,两个Bean类都位于不同的包中,甚至实现了不同的方法。 所需的MediaType传递到WebTarget#request()方法,该方法返回同步Invocation.Builder的实例。 以HTTP动词( GETPOSTPUTDELETEHEADOPTIONSTRACE )命名的方法的最终调用将启动同步请求。

新的客户端API还支持异步资源调用。 如前所述, Invocation实例将请求与提交分离。 可以通过链接的async()方法调用来发起异步请求,该调用将返回AsyncInvoker实例。 参见清单17

清单17

@Testpublic void roasterFuture() throws Exception {//...Future<Response> future = this.root.path("roaster").path("roast-id").request().async().post(entity);Response response = future.get(5000, TimeUnit.SECONDS);Object result = response.getEntity();assertNotNull(result);assertThat(roasted.getBlend(),containsString("The dark side of the bean"));}

在上面的示例中,“准异步”通信方式没有太多好处-客户端仍然必须阻止并等待直到响应到达。 但是,基于Future的调用对于批处理非常有用:客户端可以一次发出多个请求,收集Future实例,然后再处理它们。

可以通过回调注册来实现真正的异步实现,如清单18所示:

清单18

@Testpublic void roasterAsync() throws InterruptedException {//...final Entity<Bean> entity = Entity.entity(origin, mediaType);this.root.path("roaster").path("roast-id").request().async().post(
entity, new InvocationCallback<Bean>() {public void completed(Bean rspns) {}public void failed(Throwable thrwbl) {}});}

对于每个返回Future方法,都有相应的回调方法可用。 InvocationCallback接口的实现被接受为方法的最后一个参数post()在上面的示例中为post() ,并在成功调用有效负载或发生异常情况(异常情况下)时被异步通知。

可以使用内置的模板机制简化URI的自动构造。 可以在执行请求之前不久替换预定义的占位符,并保存WebTarget实例的重复创建:

清单19

@Testpublic void templating() throws Exception {String rootPath = this.root.getUri().getPath();URI uri = this.root.path("{0}/{last}").resolveTemplate("0", "hello").resolveTemplate("last", "REST").getUri();assertThat(uri.getPath(), is(rootPath + "/hello/REST"));}

一个很小但很重要的细节:在客户端,初始化时未发现扩展; 而是必须在Client实例中显式注册它们: ClientFactory.newClient().register(PayloadVerifier.class) 。 但是,可以在客户端和服务器之间共享相同的实体拦截器实现,从而简化了测试,减少了潜在的错误并提高了生产率。 已经引入的PayloadVerifier拦截器也可以重复使用,而无需在客户端进行任何更改。

结论:是否使用Java EE?

有趣的是,JAX-RS甚至不需要成熟的应用程序服务器。 满足指定的上下文类型后,符合JAX-RS 2.0的API可以是任何东西。 但是,与EJB 3.2的结合带来了异步处理,池化(以及节流)和监视。 与Servlet 3+的紧密集成通过AsyncContext支持对@Suspended响应进行了高效的异步处理,并且CDI运行时带来了事件。 此外,Bean验证已很好地集成在一起,可用于验证资源参数。 结合使用JAX-RS 2.0和其他Java EE 7 API,可以将对象公开给远程系统,这是最方便(=无配置)和生产力最高(=无需重新发明)的方式。

也可以看看

  • 高枕无忧
  • 泽西岛
  • JAX-RS 2.0规范
  • 现实世界中的Java EE模式-重新思考最佳实践
  • HTTP RFC
  • Java EE 6观察者
  • 消化器

作者简介:顾问兼作者Adam Bien是Java EE 6/7,EJB 3.X,JAX-RS和JPA 2.X JSR的专家组成员。 从JDK 1.0开始,他就与Java技术合作,并与servlets / EJB 1.0合作。现在,他是Java SE和Java EE项目的架构师和开发人员。 他编辑了几本有关JavaFX,J2EE和Java EE的书,并且是《 Real World Java EE Patterns — Rethinking Best Practices and Real World Java EE Night Hacks》的作者 。 Adam还是Java冠军,2012年Java大使,JavaOne 2009、2011年和2012 Rock Star。 Adam在慕尼黑的机场偶尔组织Java(EE)研讨会。

经Oracle公司Oracle技术网许可转载

翻译自: https://jaxenter.com/java-ee-7-and-jax-rs-2-0-106101.html

input发送a.jax

input发送a.jax_Java EE 7和JAX-RS 2.0相关推荐

  1. input发送a.jax_Java EE 7 / JAX-RS 2.0:具有自定义HTTP标头的简单REST API身份验证和授权...

    input发送a.jax 在使用已可用的HTTP协议实施Web服务时,REST带来了很多便利. 通过仅通过指定的URL触发GET,POST和其他HTTP方法,您将确保通过REST服务的响应来完成某些工 ...

  2. input发送a.jax_Java EE 7 / JAX-RS 2.0 – REST上的CORS

    input发送a.jax Java EE REST应用程序在开箱即用的开发机器上通常可以很好地运行,在该机器上,所有服务器端资源和客户端UI都指向" localhost"或127. ...

  3. input发送a.jax_Java REST JAX-RS 2.0 –如何处理日期,时间和时间戳记数据类型

    input发送a.jax 无论是X-Form-Urlencoded还是JSON HTTP发布到REST资源端点,对于与日期或时间相关的数据都没有特定的"数据类型". 大多数开发人员 ...

  4. input发送a.jax_JAX-RS 2.0:服务器端处理管道

    input发送a.jax 这篇文章的灵感来自JAX-RS 2.0规范文档 (附录C)中的Processing Pipeline部分. 我喜欢它的原因在于它提供了JAX-RS中所有模块的漂亮快照-以准备 ...

  5. input发送a.jax_JAX-RS 2.0的新功能– @BeanParam批注

    input发送a.jax 至少可以说JAX-RS很棒,也是我的最爱之一! 为什么? 功能丰富 直观(因此学习曲线不那么陡峭) 易于使用和开发 具有出色的RI – Jersey , RestEasy等 ...

  6. input发送a.jax_JAX-RS 2.0:自定义内容处理

    input发送a.jax 我试图想到一个更好的标题,但未能拿出一个! 请多多包涵--. JAX-RS 2.0规范允许我们无缝地将JAXB对象编组到HTTP请求/响应主体,或从HTTP请求/响应主体中解 ...

  7. input发送a.jax_与时俱进:在JAX-RS API中采用OpenAPI v3.0.0

    input发送a.jax 看到时间流逝如此之快,真是太恐怖了! OpenAPI规范3.0.0是对Swagger规范的重大改进,大部分已于一年前发布,但工具赶上了一段时间. 但是,随着最近Swagger ...

  8. input发送a.jax_JAX-RS 2.0中的透明PATCH支持

    input发送a.jax PATCH方法是最不受欢迎的HTTP方法之一,因为直到最近才真正没有一种标准的PATCH格式. 一段时间以来,它已经针对JSON进行了标准化,因此有很多库可以为您完成繁重的工 ...

  9. ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n

    ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n ...

最新文章

  1. 微软网站打不开_强烈建议收藏,微软出了自家「协作白板」应用
  2. iOS 仿通讯录索引
  3. 计算机专业开学周记,【热门】开学周记集锦5篇
  4. OpenCV基本线性变换轨迹栏的实例(附完整代码)
  5. [置顶]信息发布系统 Jquery+MVC架构开发(4)Model 层
  6. 使用SpringTask定时获取传感器设备信息并缓存到Redis
  7. 使用UTL_FILE在oracle中读写文本数据
  8. Swift傻傻分不清楚系列(六)集合类型
  9. 坚持一个好习惯该有多难?
  10. 敲了 10000 小时代码,我也没能成为一名高级程序员
  11. MFC PreTranslateMessage介绍
  12. 学了python做什么自由职业者_我又有一位程序员朋友成了自由职业者
  13. python的前端和后端_python是前端还是后端
  14. python进行主成分分析_python 主成分分析
  15. 野火STM32F429学习笔记
  16. excel取消隐藏_Excel教程:一键取消隐藏工作表
  17. 网络安全笔记-18-ICMP 协议
  18. Edit Control响应全选(Ctrl+A)
  19. 上位机串口数据检验方式(二)——奇偶校验
  20. GO 重新进阶学习(四)

热门文章

  1. unzip unbuntu 中文乱码
  2. Excel中提取单元格数字
  3. ubuntu8.04安装配置
  4. redis-manger管理平台
  5. 最快的计算机操作,自学电脑操作怎样比较快?
  6. python将电视剧按收视率进行排序_Python爬虫实现数据可视化,卫视实时收视率对比,就是如此强大!...
  7. 海尔空调、新风系统加装wifi模块
  8. java中将两个图片进行叠加
  9. kb mac压缩图片大小_Mac系统怎么压缩图片
  10. 关于 Win10 截图 截屏 原生截图工具 基础使用