Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Fetch API通过React应用程序调用servlet-无法加载资源错误(406-不可接受)_Java_Reactjs_Servlets_Jersey_Fetch Api - Fatal编程技术网

Java 使用Fetch API通过React应用程序调用servlet-无法加载资源错误(406-不可接受)

Java 使用Fetch API通过React应用程序调用servlet-无法加载资源错误(406-不可接受),java,reactjs,servlets,jersey,fetch-api,Java,Reactjs,Servlets,Jersey,Fetch Api,我对React JS和Java servlet非常陌生。我使用Jersey在React中创建了一个视图,在servlet中创建了一个API端点。前端和后端都在本地机器上的Tomcat服务器上运行。servlet尝试访问运行在http://localhost:37070/expenseClaimService/start发布新的索赔。此服务将单独测试,并返回创建的新索赔的id 现在,我正试图使用React应用程序中的Fetch调用servlet中的端点。但是,我一直收到加载资源失败:服务器在Rea

我对React JS和Java servlet非常陌生。我使用Jersey在React中创建了一个视图,在servlet中创建了一个API端点。前端和后端都在本地机器上的Tomcat服务器上运行。servlet尝试访问运行在
http://localhost:37070/expenseClaimService/start
发布新的索赔。此服务将单独测试,并返回创建的新索赔的
id

现在,我正试图使用React应用程序中的
Fetch
调用servlet中的端点。但是,我一直收到
加载资源失败:服务器在React app中以406
的状态响应

React应用程序中的提取调用

  handleAddClaim = () => {
    console.log("in method");
    fetch("http://localhost:8080/eca/api/claims/new-claim", {
      method: "POST",
      headers: {
        Accept: "text/plain",
        "Content-Type": "application/json",
        "Access-Control_Allow-Orign": "*"
      },
      body: JSON.stringify({
        empName: "Test Vendor4",
        empFirstname: "Test",
        empLastname: "Vendor4",
        empEmail: "test4@mail.com",
        empId: "test3",
        empJobTitle: "SE",
        date: "08 December, 2018",
        refNo: "testRef999",
        memo: "OPD test claim 11",
        claims: [
          {
            amount: "9500.00",
            memo: "Test claim - Medicine",
            billDate: "4 December, 2018"
          }
        ]
      })
    })
    .then(response => {
        console.log(response);
    })
    .catch(error => {
        console.error(error);
    });
  };
Servlet中的端点

@Path("/claims")
public class OPDClaimEndpoint {

    @POST
    @Path("/new-claim")
    @Produces(MediaType.TEXT_HTML)
    @Consumes(MediaType.APPLICATION_JSON)
    public String addNewClaim(JsonObject body){            
        return ExecutionUtils.generatePostRequest(body.toString());
    }
}
生成post请求(使用Apache HttpClient)

web.xml

<servlet>
    <servlet-name>eca-api</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.org.eca.client.api.endpoint</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>eca-api</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

eca api
com.sun.jersey.spi.container.servlet.ServletContainer
com.sun.jersey.config.property.packages
com.org.eca.client.api.endpoint
com.sun.jersey.api.json.POJOMappingFeature
真的
1.
eca api
/原料药/*
如何解决此问题,以便我可以从React应用程序调用服务?
非常感谢您的帮助。

查看您的fetch调用和Servlet端点,您的
@products
注释指定Servlet将生成“text/html”,而fetch调用指定它将只接受“text/plain”类型(“accept”标题)


尝试至少更改其中一个(取决于您的需要)以相互匹配,问题应该得到解决。

查看您的获取调用和Servlet端点,您的
@生成的
注释指定Servlet将生成“text/html”,而获取调用指定它将只接受“text/plain”类型(“接受”标题)


尝试至少更改其中一个(取决于您的需要)以相互匹配,问题应该得到解决。

您需要发送JSON类型,因此将ACCEPT替换为

与:

HTTP内容类型标头字段名


您需要发送JSON类型,因此将ACCEPT替换为

与:

HTTP内容类型标头字段名


终于找到了解决办法

在tomcat日志文件中,可以看到Jersey不支持Gson的JsonObject


正如答案所指出的,Jersey只支持本机类型和
String
作为其方法的输入。因此,我将端点方法签名改为接受字符串,
public String addNewClaim(String body)
,现在它甚至可以与庞大的Json字符串一起工作。(注意,Jersey 1.19中有此功能,Jersey 2.x中可能有所不同)。但是它可以像本文中所说的那样接收Java对象。

终于找到了解决方案

在tomcat日志文件中,可以看到Jersey不支持Gson的JsonObject

正如答案所指出的,Jersey只支持本机类型和
String
作为其方法的输入。因此,我将端点方法签名改为接受字符串,
public String addNewClaim(String body)
,现在它甚至可以与庞大的Json字符串一起工作。(注意,Jersey 1.19中有此功能,Jersey 2.x中可能有所不同)但是它可以像本文中所说的那样接收Java对象。

尝试了下面的两种答案(在标题中设置
内容类型
,并将所有输入输出类型更改为
应用程序/json
),现在它给出了415-不支持的媒体类型。在postman中调用时也给出了相同的错误。尝试了下面的两种答案(在标题中设置
CONTENT-TYPE
,并将所有输入输出类型更改为
application/json
),现在它给出415-不支持的媒体类型。在postman中调用时也会给出相同的错误。
<servlet>
    <servlet-name>eca-api</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.org.eca.client.api.endpoint</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>eca-api</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>
request.setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
request.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);