2013-07-29 7 views
1

현재 응답 처리를 방해하고 사용자에게 404를 반환하는 서비스 (또는 다른 비 컨트롤러 메서드)에서 제기 할 수있는 예외 또는 다른 것이 있습니까?서비스가 404 응답을 반환 할 수 있습니까?

장고 세계에서 get_object_or_404이 발생하면이 효과가있는 Http404 예외가 발생합니다. 나는 서비를 쓰고있다. 해당 서비스에서 요청한 객체가 사용자에게 액세스 할 수 없다고 판단한 경우 (이 경우 아직 게시되지 않음) 404 실행을 중지하고 나머지 실행을 중단하고 싶습니다. 목표는 서비스를 DRY로 호출하는 컨트롤러가 항상 def obj = someService.getSomething(); if (obj) {} else { render status: 404} 호출을 반복하는 것은 아닙니다.

요약 :
장고, 나는이 컨트롤러에서 Grails의 에 NOT을이 작업을 수행하는 동등한 또는 방법이 있나요 요청 처리를 중지하고 404을 반환하는 임의의 지점에서 Http404를 제기 할 수 있습니까?

+3

컨트롤러에서 상태 코드를 반환하지 않으려는 이유가 확실하지 않습니다. 우선 Java/Groovy로 시작한 이래로 구현하는 적절한 방법이라고 알려졌습니다 (서비스가 예외를 throw하고 컨트롤러가 캐치하고 상태 코드를 반환 함). 서비스는 요청 처리에 대해 아무 것도 알지 못하며 컨트롤러는 비즈니스 로직에 대해 아무것도 모릅니다. –

답변

4

com.my.ResourceNotFoundException과 같은 예외 클래스를 생성 한 다음 원하는 곳 (컨트롤러 또는 서비스)에서 던져 버리십시오.

는 아래와 같은 컨트롤러를 만듭니다

class ErrorController { 

    def error404() { 
     response.status = HttpStatus.NOT_FOUND.value() 
     render([errors: [[message: "The resource you are looking for could not be found"]]] as JSON) 
    } 
} 

그런 다음 UrlMappings.groovy 구성 파일에이 컨트롤러 액션과 해당 유형의 예외를 처리 할 항목을 추가 할 수 있습니다. 패턴으로 "500"을 지정하면 throw 된 ResourceNotFoundException과 같은 500 개의 오류를 catch하고 예외가 해당 유형과 일치하면 지정된 컨트롤러 및 조치가 사용됩니다.

"500"(controller: "error", action: "error404", exception: ResourceNotFoundException) 
3

컨트롤러에서 원하는 코드로 응답 상태를 설정할 수 있습니다.

response.status = 404 

또한 함께 render를 사용할 수있는 status-from the docs : 당신은 서비스 대표는 서비스 메소드를 호출이 이전 할 컨트롤러를 가질 수 있습니다, 또는 당신은 당신의 서비스를 할 수 있습니다

// render with status code 
render(status: 503, text: 'Failed to update book ${b.id}') 

컨트롤러에 상태 코드를 반환합니다.

+1

404 대신에'org.springframework.http.HttpStatus.NOT_FOUND.value'를 사용하도록 제안하고 싶습니다. – dmahapatro

+0

그렇습니다. 컨트롤러 내에서 그렇게하는 방법입니다.하지만 제 질문은 컨트롤러에서 컨트롤러를 사용하지 않는 것입니다. 서비스에서. 나는 DRY를 시도하고 모든 컨트롤러에서 수표를 반복하지 않고 404 렌더링을 시도합니다. – smacintyre

0

@doelleri는 상태 코드 렌더링을 위해 정확히 수행 할 수있는 작업을 언급했습니다.

컨트롤러에서 DRYness를 달성 할 수있는 "그리 좋지 않은"방법이 아래에 나와 있습니다. 그러나 try try 블록을 유틸리티로 옮기고 싶다면 더 많은 것을 얻을 수 있습니다.

//Custom Exception 
class CustomException extends Exception{ 
    Map errorMap 

    CustomeException(Map map, String message){ 
     super(message) 
     this.errorMap = map 
    } 
    .... 
} 

//service 
def getSomethingGood(){ 
    .... 
    .... 
    if(something bad happened){ 
     throw new CustomException([status: HttpStatus.NOT_FOUND.value, 
            message: "Something really got messed up"], 
            "This is a custom Exception") 
     //or just return back from here with bad status code 
     //and least required data 
    } 
    ...... 
    return goodObj 
} 

def getSomething(){ 
    def status = HttpStatus.OK.value 
    def message 
    try{ 
     def obj = getSomethingGood() 
     message = "success value from obj" 
     //or can also be anything got from obj etc 
    } catch(CustomException c){ 
     status = c.errorMap.status 
     message = c.errorMap.message 
    } 

    [status: status, message: message] 
} 

//controller 
def obj = someService.getSomething() 
render(status: obj.status, text: obj.message) 

또한 확인 된 예외를 처리 할 때 트랜잭션은 서비스 계층에서 롤백되지 않습니다. 이 질문의 범위를 벗어난 것으로 생각되는 다른 일이 있습니다.

+2

그리고 나는 투표가 실패한 이유를 알고 싶습니다. :) – dmahapatro