首页 文章

使用Fetch API通过React app调用servlet - 无法加载资源错误(406 - Not Acceptable)

提问于
浏览
0

我是React JS和Java servlet的新手 . 我使用Jersey在React中创建了一个视图,在servlet中创建了一个API endpoints . 前端和后端都在我本地计算机上的Tomcat服务器上运行 . servlet尝试访问在 http://localhost:37070/expenseClaimService/start 运行的服务以发布新的声明 . 此服务单独测试,并返回创建的新声明的 id .

现在我尝试使用React应用程序中的 Fetch 来调用servlet中的 endpoints . 但是我一直在React app中收到 Failed to load resource: the server responded with a status of 406 .

The fetch call in React app

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);
    });
  };

Endpoint in 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());
    }
}

Generating post request (using Apache HttpClient)

public static String generatePostRequest(String input){
    String url = "http://localhost:37070/expenseClaimService/start";

    try {
        StringEntity requestEntity = new StringEntity(
                input,
                ContentType.APPLICATION_JSON);

        HttpPost request = new HttpPost(url);
        request.setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
        request.setEntity(requestEntity);
        HttpClient client = HttpClientBuilder.create().build();
        HttpResponse response = client.execute(request);
        return response.toString();
    }
    catch ( IOException e) {
        logger.info(e.getMessage());
    }
    return "Failed";
}

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>

如何解决此问题以便我可以从React应用程序调用该服务?任何帮助深表感谢 .

3 回答

  • 1

    终于找到了解决方案!

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

    正如this SO回答所示,Jersey只支持本机类型和 String 作为其方法的输入 . 所以我改变了 endpoints 方法签名以接受字符串, public String addNewClaim(String body) ,现在它甚至可以使用庞大的Json字符串 . (请注意,这是在Jersey 1.19中,在Jersey 2.x中可能有所不同) . 但是它可以接受Java对象,如answer中所述 .

  • 0

    你需要 send JSON 类型,所以用CONTENT_TYPE替换ACCEPT

    request.setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
    

    附:

    request.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
    

    HTTP Content-Type标头字段名称 .

  • 1

    看着你获取调用和Servlet endpoints ,你的 @Produces 注释指定servlet将产生"text/html",而Fetch调用指定它只接受"text/plain"类型("Accept"头) .

    尝试更改其中至少一个(取决于您需要的)以相互匹配,并且应该修复问题 .

相关问题