У меня проблема с публикацией метода в моей программе java rest api. Я использую как back-end: jersey и hibernate и как front-end: angular. когда я использую веб-службу с помощью метода post в приложении angular и тестовой программе в веб-браузере, браузер консоли показывает ошибку как:
"Failed to load resource: the server responded with a status of 405 (Non Allowed Method)"
Я вижу учебник по этой проблеме, и он дает мне решение, в котором используется CORS, который управляет методом http, и я понимаю CORS, но мои проблемы: -как закодировать этот CORS в моей Java-программе? -должен ли я создать класс с помощью метода CORS? -когда в моей программе я должен вызывать CORS? Пожалуйста, помоги мне. большое спасибо
это отдых api
package com.ws.rest;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.ws.dao.DaoFactory;
import com.ws.entity.Personne;
import com.ws.jpa.PersonneJPA;
@Path("/personne")
public class PersonneRest {
private PersonneJPA jpa_personne;
public PersonneRest() {
this.jpa_personne = DaoFactory.getInstance().get_personne();
}
/*
* #########################################################################
* PROCEDURES
* #########################################################################
*/
// Getall
@Path("/getall")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Personne> getAll() {
return jpa_personne.findAll();
}
// Get par ID
@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Personne getById(@PathParam("id") long id) {
List<Personne> h_personne = jpa_personne.findById(id);
if (h_personne == null)
return null;
return h_personne.get(0);
}
// Ajout d'un enregistrement de type Langue
@Path("/add")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void add(Personne personne) {
jpa_personne.add(personne);
}
// Mise a jour d'un enregistrement de type Langue
@Path("/update")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void update(Personne personne) {
jpa_personne.update(personne);
}
// Suppression d'un enregistrement de type Langue
@Path("/delete")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void delete(Personne personne) {
jpa_personne.delete(personne);
}
}
Вот web.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation = "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id = "WebApp_ID" version = "3.1">
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Define the ResourceConfig class -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.ws.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all the URLs to the Jersey ServletContainer -->
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>





Для обработки CORS на сервере вы должны использовать Фильтр запросов / ответов Джерси. Этот фильтр правильно обрабатывает как Запрос CORS Preflight, так и обычный запрос CORS.
Если вы используете сканирование пакетов для регистрации своих ресурсов и поставщиков, то фильтр должен автоматически регистрироваться из-за аннотации @Provider.
@Provider
@PreMatching
public class CorsFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext request) throws IOException {
if (isPreflightRequest(request)) {
request.abortWith(Response.ok().build());
return;
}
}
private static boolean isPreflightRequest(ContainerRequestContext request) {
return request.getHeaderString("Origin") != null
&& request.getMethod().equalsIgnoreCase("OPTIONS");
}
@Override
public void filter(ContainerRequestContext request, ContainerResponseContext response)
throws IOException {
if (request.getHeaderString("Origin") == null) {
return;
}
if (isPreflightRequest(request)) {
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.getHeaders().add("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, " +
"Accept-Version, Content-Length, Content-MD5, CSRF-Token");
}
response.getHeaders().add("Access-Control-Allow-Origin", "*");
}
}
Чтобы зарегистрировать фильтр, вы хотите поместить пакет, в котором находится фильтр, в param-value для init-param, который сообщает Джерси сканировать эти пакеты для ваших ресурсов и поставщиков. Итак, если ваш фильтр находится в com.ws.util, вы должны сделать следующее
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.ws.rest, com.ws.util</param-value>
</init-param>
Обратите внимание, я только что добавил пакет, разделенный запятой. Вы также можете отключить два перечисленных пакета просто для com.ws. Сканирование пакетов является рекурсивным, поэтому просто перечисление родительского пакета приведет к тому, что сканирование достигнет обоих com.ws.restиcom.ws.util.
Вам просто нужно зарегистрировать его, и он автоматически вызывается для всех запросов. Если вам нужна помощь в регистрации, опубликуйте конфигурацию приложения]
спасибо большое, я просто регистрирую этот класс и все нормально
Смотрите мой Обновлять. Это то, что вам нужно сделать, чтобы зарегистрировать фильтр.
Спасибо, все в порядке. последний вопрос. какие ключевые слова я набираю для оптимизации своих кодов? Мне нужно оптимизировать свой код, потому что я не думаю об оптимизации кодов.
Большое спасибо за ваши ответы. на данный момент это просто определение класса CorsFilter, но я хотел бы знать, как его использовать, чтобы программа учитывала этот CORS при выполнении остального API? пожалуйста, не могли бы вы дать мне пример, как использовать его с остальными api (com.ws.rest)?