簡體   English   中英

無法通過Angular JS訪問在Tomcat上部署的Spring Rest Web服務

[英]unable to access a spring Rest web service deploy on tomcat through angular JS

大家好,我一直在瀏覽與該問題有關的帖子,但沒有找到解決問題的方法。 實際上,我有一個執行某些任務(后端)的spring RestController,我想通過angularJs應用程序使用這些服務,但出現以下錯誤消息

"XMLHttpRequest cannot load http://localhost:8084/BackendHibernateJPA/abonnes. Origin http://localhost:8383 is not allowed by Access-Control-Allow-Origin. (14:19:15:639 | error, javascript)
  at app/index.html" 

當我運行Spring Rest項目時,可以在瀏覽器中找到預期的結果。 我也可以通過諸如“ Chrome Rest客戶端”之類的其他客戶端獲得結果,但是我無法使用angularJS來提供服務

這是我的RestController

import com.mycompany.backendhibernatejpa.service.IAbonneService;
import com.mycompany.backendhibernatejpa.entities.Abonne;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;

/**
 *
 * @author 
 */
@CrossOrigin(origins = {"http://localhost:8383"}, methods = {RequestMethod.DELETE, RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT}, allowedHeaders = "true")
@RestController
@RequestMapping("/abonnes")
public class AbonneController {

    @Autowired
    private IAbonneService iAbonneService; //Service which will do all data retrieval/manipulation work

    //-------------------Retrieve All Abonne--------------------------------------------------------
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ResponseEntity<List<Abonne>> findAllAbonnes() throws Exception {
        List<Abonne> listAbonnes = iAbonneService.findAll();
        if (listAbonnes.isEmpty()) {
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
        }
        return new ResponseEntity<>(listAbonnes, HttpStatus.OK);
    }

    @RequestMapping(value = "/some/{idDomicile}", method = RequestMethod.GET)
    public ResponseEntity<List<Abonne>> findSomeAbonnes(@PathVariable("idDomicile") long idDomicile) throws Exception {
        List<Abonne> listAbonnes = iAbonneService.findSomeAbonne(idDomicile);
        if (listAbonnes.isEmpty()) {
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
        }
        return new ResponseEntity<>(listAbonnes, HttpStatus.OK);
    }

    //-------------------Retrieve Single Abonne--------------------------------------------------------
    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Abonne> findAbonneById(@PathVariable("id") long id) throws Exception {
        System.out.println("Fetching User with id " + id);
        Abonne user = iAbonneService.findById(id);
        if (user == null) {
            System.out.println("Abonne with id " + id + " not found");
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<>(user, HttpStatus.OK);
    }
    //-------------------Create an Abonne--------------------------------------------------------

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public ResponseEntity<Void> createAbonne(@RequestBody Abonne abonne, UriComponentsBuilder ucBuilder) throws Exception {
        iAbonneService.create(abonne);
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(ucBuilder.path("/abonne/{id}").buildAndExpand(abonne.getId()).toUri());
        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    //------------------- Update a Abonne --------------------------------------------------------
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public ResponseEntity<Abonne> updateAbonne(@PathVariable("id") long id, @RequestBody Abonne abonne) throws Exception {
        System.out.println("Updating Abonne " + id);
        Abonne currentAbonne = iAbonneService.findById(id);
        if (currentAbonne == null) {
            System.out.println("Abonne with id " + id + " not found");
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
        currentAbonne.setNomAbonne(abonne.getNomAbonne());
        currentAbonne.setTel(abonne.getTel());
        iAbonneService.update(currentAbonne);
        return new ResponseEntity<>(currentAbonne, HttpStatus.OK);
    }

    //------------------- Delete a Abonne --------------------------------------------------------
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public ResponseEntity<Abonne> deleteUser(@PathVariable("id") long id) throws Exception {
        System.out.println("Fetching & Deleting User with id " + id);
        Abonne abonne = iAbonneService.findById(id);
        if (abonne == null) {
            System.out.println("Unable to delete. Abonne with id " + id + " not found");
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
        iAbonneService.delete(abonne);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
}

這是我的servlet

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans    
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <context:component-scan base-package="com.mycompany.backendhibernatejpa.controller" />
    <mvc:annotation-driven />
    <bean id="iAbonneDao" class="com.mycompany.backendhibernatejpa.daoImpl.AbonneDaoImpl"/> 
    <bean id="iAbonneService" class="com.mycompany.backendhibernatejpa.serviceImpl.AbonneServiceImpl"/>

    <!-- couche de persistance JPA -->
    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">            
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
                <property name="generateDdl" value="true" />
                <property name="showSql" value="true" />
            </bean>
        </property>
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
    </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   
        <property name="locations" value="classpath:bd.properties"/>
    </bean>

    <!-- la source de donnéees DBCP -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
        <property name="driverClassName" value="${bd.driver}" />
        <property name="url" value="${bd.url}" />
        <property name="username" value="${bd.username}" />
        <property name="password" value="${bd.password}" />
    </bean>

    <!-- le gestionnaire de transactions -->

    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>


    <!-- traduction des exceptions -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

    <!-- annotations de persistance -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <!--    <bean id="springSecurityFilterChain" class="org.springframework.web.filter.DelegatingFilterProxy"/>-->

</beans>

我什至在我的web.xml中添加了它

<!--     ================== Built In Filter Definitions ===================== -->   

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
    </init-param>
    <init-param>
        <param-name>cors.support.credentials</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>cors.preflight.maxage</param-name>
        <param-value>10</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- ==================== Built In Filter Mappings ====================== -->

最后,這是我的角度服務

'use strict';

var services = angular.module('myApp.services', ['ngResource']);
services.factory('abonneFactory', function ($resource) {
    return $resource('http://localhost:8084/BackendHibernateJPA/abonnes/', {}, {
        query: {method: 'GET', isArray: true},
        create: {method: 'POST'}
    });
});
services.factory('abonneFactory', function ($resource) {
    return $resource('http://localhost:8084/BackendHibernateJPA/abonnes/:id', {}, {
        show: {method: 'GET'},
        update: {method: 'PUT', params: {id: '@id'}},
        delete: {method: 'DELETE', params: {id: '@id'}}
    });
});

通過錯誤消息,這似乎是CORS問題Access-Control-Allow-Origin 站點A嘗試從站點B獲取內容時,就會發生這種情況。 您應該在應用程序中實現CORS ,並在后端添加以下標頭:

public static final HttpHeaders HTTP_HEADERS = new HttpHeaders();
static{
    HTTP_HEADERS.add("Access-Control-Allow-Headers", "Content-Type");
    HTTP_HEADERS.add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
    HTTP_HEADERS.add("Access-Control-Allow-Origin", "*");
}

並將這些標頭添加到服務響應中,例如:

@RequestMapping(value = "/some/{idDomicile}", method = RequestMethod.GET)
public ResponseEntity<List<Abonne>> findSomeAbonnes(@PathVariable("idDomicile") long idDomicile) throws Exception {
    List<Abonne> listAbonnes = iAbonneService.findSomeAbonne(idDomicile);
    if (listAbonnes.isEmpty()) {
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
    }
    return new ResponseEntity.ok().headers(HTTP_HEADERS).body(listAbonnes);
}

另一種選擇是在瀏覽器中使用擴展程序

對於Chrome: https //chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl = zh-CN

對於Firefox https://addons.mozilla.org/zh-CN/firefox/addon/cross-domain-cors/

我終於解決了我在Spring網站上發現的問題

更改靜態資源后,可能需要強制瀏覽器重新加載靜態資源。 在Chrome(和帶有插件的Firefox)中,您可以使用“開發人員工具”(F12),這可能就足夠了。 或者,您可能必須使用CTRL + F5。

我真的不明白為什么,但是對我有用。 因此,@ CrossOrigin足以配置跨域資源共享

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM