使用 Spring MVC 和 AngularJS 的方法 DELETE

Posted

技术标签:

【中文标题】使用 Spring MVC 和 AngularJS 的方法 DELETE【英文标题】:Method DELETE with Spring MVC and AngularJS 【发布时间】:2015-05-08 12:04:36 【问题描述】:

我的 RESTfull 服务有问题,应该从数据库中删除记录。当我使用 REST 请求以角度调用函数时,我收到 FireBug 错误消息:“NetworkError: 403 Forbidden - http://localhost:8080/sake/dict/technologies”。问题仅在于 DELETE 方法 - GET、POST 工作正常。

Angular 中的服务

(function(angular) 
'use strict';
angular.module('dictionaryService', ['ngResource'])
    .factory('dictTechnologies', [ '$resource', function($resource) 
        return $resource('http://localhost:8080/sake/dict/technologies/:id', id: '@id' , 
            query: method:'GET', isArray:true,
            create: method:'POST',
            delete: method:'DELETE', params: id: '@id'
        );
    ]).factory('dictDocuments', [ '$resource', function($resource) 
        return $resource('http://localhost:8080/sake/dict/documents/:Id', Id: "@Id" , 
            query: method:'GET', isArray:true,
            create: method:'POST',
            delete: method:'DELETE'
        );
    ]);
)(window.angular);

HTML我按下按钮

 <button ng-click="deleteBtn()" class="btn btn-primary btn-xs"> Delete [x] </button>

Angular 控制器中的功能

$scope.deleteBtn= function() 
        var z = $scope.technologies[1].id; //here is JSON of technologu which I recieved in GET response
        console.log(z);
        dictTechnologies.delete(z).$promise.then(function(z) 
            //if success
        , function(errResoponse) 

        );
    ;

Java Spring MVC 中的控制器 为了简化示例,我只需调用 System.out.println();

@Controller
@RequestMapping("/dict")
public class SlownikController 


    @Autowired
    SlTechnologiaDao slTechnologiaDao;

//GET work fine
        @RequestMapping(value = "/technologies", method = RequestMethod.GET)
        public @ResponseBody List<SlTechnologia> getAllTechnologies() 
 return slTechnologiaDao.getAllTechnologia();
        

    @RequestMapping(value = "/technologies/id", method = RequestMethod.DELETE)
    public @ResponseBody int deleteTechnology(@RequestParam("id")/* @PathParam("id")*/ Integer id) 
        System.out.println(id);
        return 1;
    


AplicationContext - servlet

<!-- Configure to plugin JSON as request and response in method handler -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonMessageConverter" />
            </list>
        </property>
    </bean>

    <!-- Configure bean to convert JSON to POJO and vice versa -->
    <bean id="jsonMessageConverter"
        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    </bean>

我读了很多页,到处都是一样的方法:

@RequestMapping(value = "/technologies/id", method = RequestMethod.DELETE)
        public @ResponseBody int deleteTechnology(@RequestParam("id")/* @PathParam("id")*/ Integer id) 
            System.out.println(id);
            return 1;
        

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

您将 id 作为路径变量传递,但试图将其作为请求参数获取。将您的方法更改为

 @RequestMapping(value = "/technologies/id", method = RequestMethod.DELETE)
 public @ResponseBody int deleteTechnology(@PathVariable("id") Integer id) 
        System.out.println(id);
        return 1;
 

@RequestParam是一个注解,表示方法参数应该绑定到Web请求参数,而@PathVariable是一个注解,表示方法参数应该绑定到URI模板变量。

【讨论】:

同样的错误。在 Tomcat 的控制台中,他们似乎没有收到来自 Angular 的任何请求 - 控制台中没有任何新消息甚至错误。 您能否验证您确实发送了有效的id,并且您撰写的网址是否正确?由于您的 GET 方法工作正常,我假设配置很好,并且您映射 DELETE 也很好,所以问题可能出在客户端发出请求。 FireBug 中来自网络的信息:HTTP/1.1 403 禁止服务器:Apache-Coyote/1.1 内容类型:文本/纯文本内容长度:0 日期:2015 年 3 月 6 日星期五 20:22:10 GMT OPTIONS /sake/dict/technologies HTTP/1.1 主机:localhost:8080 用户代理:Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: text/html,application/xhtml+ xml,application/xml;q=0.9,/;q=0.8 Accept-Language: pl,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Origin: localhost:8000 Access-Control-Request-Method: DELETE Con​​nection: keep-alive and from console.log(z) return: 2 您可以尝试通过任何 Rest Client 直接访问 URL (localhost:8080/sake/dict/technologies/1) 吗?无论如何,您将获得 403 禁止,这意味着可以访问并理解来自客户端的请求,但服务器拒绝采取任何进一步的操作。您有任何特定的安全配置、标头吗? 我安装了 HTTP 资源测试,就可以了。所以我的角度客户端出了点问题。嗯,也许与 CORS 政策有关,但使用 GET 和 POST 它可以工作。在 web.xml 我有配置 CorsFilter/*【参考方案2】:

我找到了解决方案:How to make Apache Tomcat accept DELETE method

我添加到 web.xml 过滤器和 DELETE 工作:

<filter>
        <filter-name>CorsFilter</filter-name>
        <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
        <init-param>
            <param-name>cors.allowed.headers</param-name>
            <param-value>Accept,Accept-Encoding,Accept-Language,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,Connection,Content-Type,Host,Origin,Referer,Token-Id,User-Agent, X-Requested-With</param-value>
        </init-param>
        <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, PUT, DELETE, OPTIONS, HEAD</param-value>
        </init-param>
    </filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

【讨论】:

以上是关于使用 Spring MVC 和 AngularJS 的方法 DELETE的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring MVC 和 AngularJS 的方法 DELETE

Spring MVC 和 Angularjs

AngularJS 和 Spring MVC 安全性

AngularJS和Spring MVC的Ajax GET错误

将 Spring MVC 应用程序从 JSP 迁移到 AngularJS

如何提高 Spring MVC - Hibernate - JSP - AngularJS v1.6 的性能? [关闭]