为Symfony约束验证失败设置http代码

时间:2016-04-21 13:46:15

标签: php rest symfony http doctrine

很简单:当实体保存约束失败时,如何设置特定的http错误代码而不是通用500?

详细

我使用Symfony自定义约束@UniqueEntityhttp://symfony.com/doc/current/reference/constraints/UniqueEntity.html)断言保存实体时某些数据不重复。

如果此约束检查导致违规,我会获得500个http代码,而其他代码可能更合适,例如409 - 冲突(https://httpstatuses.com/409)。

我似乎无法找到有关如何覆盖验证响应的任何文档。

提前感谢您的任何建议。

2 个答案:

答案 0 :(得分:2)

也许您可以为活动创建ListenerOuter

然后你会有类似的东西:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import org.testng.annotations.Test;

import java.util.Arrays;
import java.util.List;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;

public class BrokenTest
{
    private static final String NAMESPACE = "http://example.com";

    @JacksonXmlRootElement(localName="Outer", namespace = NAMESPACE)
    public static class Outer
    {
        @JacksonXmlProperty(localName="Foo", namespace = NAMESPACE)
        public final String foo;

        @JacksonXmlProperty(localName="Inner", namespace = NAMESPACE)
        @JacksonXmlElementWrapper(localName = "Inners", namespace = NAMESPACE)
        public final List<Inner> inners;

        @JsonCreator
        public Outer(
                @JacksonXmlProperty(localName="Foo", namespace = NAMESPACE) final String foo,
                @JacksonXmlProperty(localName="XXX", namespace = NAMESPACE) final List<Inner> inners)
        {
            this.foo = foo;
            this.inners = inners;
        }
    }

    @JacksonXmlRootElement(localName="Inner", namespace = NAMESPACE)
    public static class Inner
    {
        @JacksonXmlProperty(localName="Bar", namespace = NAMESPACE)
        public final String bar;

        @JacksonXmlProperty(localName="Baz", namespace = NAMESPACE)
        public final String baz;

        @JsonCreator
        public Inner(
                @JacksonXmlProperty(localName="Bar", namespace = NAMESPACE) final String bar,
                @JacksonXmlProperty(localName="Baz", namespace = NAMESPACE) final String baz)
        {
            this.bar = bar;
            this.baz = baz;
        }
    }

    @Test
    public void serializeInner() throws Exception
    {
        Inner inner = new Inner("inner bar", "inner baz");
        ObjectMapper mapper = new XmlMapper();
        String serialized = mapper.writeValueAsString(inner);
        assertEquals(serialized, "<Inner xmlns=\"http://example.com\"><Bar>inner bar</Bar><Baz>inner baz</Baz></Inner>");
    }

    @Test
    public void deserializeInner() throws Exception
    {
        String serialized = "<Inner xmlns=\"http://example.com\"><Bar>inner bar</Bar><Baz>inner baz</Baz></Inner>";
        ObjectMapper mapper = new XmlMapper();
        Inner inner = mapper.readValue(serialized, Inner.class);
        assertNotNull(inner);
        assertEquals("inner bar", inner.bar);
        assertEquals("inner baz", inner.baz);
    }

    @Test
    public void serializeOuter() throws Exception
    {
        Outer outer = new Outer("outer foo", Arrays.asList(new Inner("inner 1 bar", "inner 1 baz"), new Inner("inner 2 bar", "inner 2 baz")));
        ObjectMapper mapper = new XmlMapper();
        String serialized = mapper.writeValueAsString(outer);
        assertEquals(serialized, "<Outer xmlns=\"http://example.com\"><Foo>outer foo</Foo><Inners><Inner><Bar>inner 1 bar</Bar><Baz>inner 1 baz</Baz></Inner><Inner><Bar>inner 2 bar</Bar><Baz>inner 2 baz</Baz></Inner></Inners></Outer>");
    }

    @Test
    public void deserializeOuter() throws Exception
    {
        String serialized = "<Outer xmlns=\"http://example.com\"><Foo>outer foo</Foo><Inners><Inner><Bar>inner 1 bar</Bar><Baz>inner 1 baz</Baz></Inner><Inner><Bar>inner 2 bar</Bar><Baz>inner 2 baz</Baz></Inner></Inners></Outer>";
        ObjectMapper mapper = new XmlMapper();
        Outer outer = mapper.readValue(serialized, Outer.class); // fails
        assertNotNull(outer);
        assertEquals("outer foo", outer.foo);
        assertEquals(2, outer.inners.size());
        assertEquals("inner 1 bar", outer.inners.get(0).bar);
        assertEquals("inner 1 baz", outer.inners.get(0).baz);
        assertEquals("inner 2 bar", outer.inners.get(1).bar);
        assertEquals("inner 2 baz", outer.inners.get(1).baz);
    }
}

答案 1 :(得分:1)

只需捕获控制器中的异常:

public function saveAction()
{
    try {
       $entity = new Entity('duplicate name');

       $this->entityManager->persist($entity);
       $this->entityManager->flush();

       return new Response();
    } catch(UniqueConstraintViolationException $e) {
       return new Response('Entity with same name already exists', Response::HTTP_CONFLICT);
    } catch (\Exception $e) {
       return new Response('Internal error', Response::HTTP_INTERNAL_SERVER_ERROR);
    }
}