Yanıtlar:
İlkbahar 3.0'dan bu yana, @ResponseStatus
ek açıklama ile bildirilen bir İstisna atayabilirsiniz:
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
...
}
@Controller
public class SomeController {
@RequestMapping.....
public void handleCall() {
if (isFound()) {
// whatever
}
else {
throw new ResourceNotFoundException();
}
}
}
@ResponseStatus
, her biri kendine ait olan güçlü bir şekilde yazılmış, iyi adlandırılmış istisna sınıflarından oluşan bir grup tanımlamanızdır @ResponseStatus
. Bu şekilde, denetleyici kodunuzu HTTP durum kodlarının ayrıntısından ayırırsınız.
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason="Your reason")
ResourceNotFound.fillInStackTrace()
boş bir uygulama ile geçersiz kılmak iyi bir fikir olabilir .
İlkbahar 5.0'dan itibaren, ek istisnalar oluşturmanız gerekmez:
throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");
Ayrıca, tek bir yerleşik istisna ile birden fazla senaryoyu kapsayabilir ve daha fazla kontrole sahip olursunuz.
Daha fazla gör:
Yöntem imzanızı HttpServletResponse
parametre olarak kabul edileceği şekilde yeniden yazın , böylecesetStatus(int)
onu .
setStatus(int)
javadoc şöyle ifade eder: Bu yöntem bir hata kodu ayarlamak için kullanılırsa, kabın hata sayfası mekanizması tetiklenmez. Bir hata varsa ve arayan kişi web uygulamasında tanımlanan bir hata sayfasını çağırmak istiyorsa, sendError
bunun yerine kullanılmalıdır.
Spring tarafından varsayılan olarak 404 için (sadece) istisna olduğunu belirtmek isterim. Ayrıntılar için Yay belgelerine bakın. Yani kendi istisnanıza ihtiyacınız yoksa bunu yapabilirsiniz:
@RequestMapping(value = "/**", method = RequestMethod.GET)
public ModelAndView show() throws NoSuchRequestHandlingMethodException {
if(something == null)
throw new NoSuchRequestHandlingMethodException("show", YourClass.class);
...
}
@PathVariable
, benim görüşüme göre herhangi bir istek işleme konulmaz. Ek açıklama eklenmiş kendi İstisnenizi kullanmanın daha iyi / daha temiz olduğunu düşünüyor musunuz @ResponseStatus(value = HttpStatus.NOT_FOUND)
?
İlkbahar 3.0.2'den beri , denetleyicinin yönteminin bir sonucu olarak ResponseEntity <T> öğesini döndürebilirsiniz :
@RequestMapping.....
public ResponseEntity<Object> handleCall() {
if (isFound()) {
// do what you want
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
(ResponseEntity <T>, @ResponseBody ek açıklamasından daha esnektir - başka bir soruya bakın )
@ControllerAdvice kullanabilirsiniz senin İstisnalar, @ControllerAdvice açıklamalı sınıf bilinen tüm Kontrolörleri yardımcı olacaktır varsayılan davranışını işlemek için.
bu yüzden herhangi bir Denetleyici 404 hatası attığında çağrılır.
aşağıdaki gibi:
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND) // 404
@ExceptionHandler(Exception.class)
public void handleNoTFound() {
// Nothing to do
}
}
ve web.xml dosyasında bu 404 yanıt hatasını aşağıdaki gibi eşleyin:
<error-page>
<error-code>404</error-code>
<location>/Error404.html</location>
</error-page>
Umarım yardımcı olur .
Belirgin cevap doğru olsa da, istisnasız bunu başarmanın bir yolu vardır. Hizmet Optional<T>
aranan nesneyi döndürüyor ve bu, HttpStatus.OK
bulunursa ve boşsa 404 ile eşleniyor.
@Controller
public class SomeController {
@RequestMapping.....
public ResponseEntity<Object> handleCall() {
return service.find(param).map(result -> new ResponseEntity<>(result, HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
}
@Service
public class Service{
public Optional<Object> find(String param){
if(!found()){
return Optional.empty();
}
...
return Optional.of(data);
}
}
Ben HttpClientErrorException , bu gibi atma tavsiye ederim
@RequestMapping(value = "/sample/")
public void sample() {
if (somethingIsWrong()) {
throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
}
}
Bunun yalnızca sunucu uygulaması çıkış akışına herhangi bir şey yazılmadan önce yapılabileceğini unutmayın.
Whitelabel Error Page \n .... \n There was an unexpected error (type=Internal Server Error, status=500). \n 404 This is your not found error
Bu biraz geç, ama Spring Data REST kullanıyorsanız o zaman zaten ek açıklama org.springframework.data.rest.webmvc.ResourceNotFoundException
kullanır @ResponseStatus
. Artık özel bir çalışma zamanı istisnası oluşturmanıza gerek yok.
Ayrıca 404 durumunu kontrol cihazınızdan döndürmek istiyorsanız, tek yapmanız gereken bunu yapmaktır
@RequestMapping(value = "/somthing", method = RequestMethod.POST)
@ResponseBody
public HttpStatus doSomthing(@RequestBody String employeeId) {
try{
return HttpStatus.OK;
}
catch(Exception ex){
return HttpStatus.NOT_FOUND;
}
}
Bunu yaptığınızda, kontrol cihazınızdan bir 404 döndürmek istediğinizde bir 404 hatası alırsınız.
Basitçe hata kodu ve 404 hata sayfası eklemek için web.xml'yi kullanabilirsiniz. Ancak 404 hata sayfasının WEB-INF altında bulunmaması gerektiğinden emin olun.
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
Bunu yapmanın en basit yolu bu ama bazı sınırlamaları var. Bu sayfa için başka sayfalar eklediğiniz aynı stili eklemek isteyip istemediğinizi varsayalım. Bu şekilde bunu yapamazsınız. Kullanmak zorunda@ResponseStatus(value = HttpStatus.NOT_FOUND)
HttpServletResponse#sendError(HttpServletResponse.SC_NOT_FOUND); return null;
denetleyici kodundan düşünün . Şimdi dışarıdan yanıt, herhangi bir denetleyiciye çarpmayan normal bir 404'ten farklı görünmüyor.
Web.xml dosyasını ayar ile yapılandırın
<error-page>
<error-code>500</error-code>
<location>/error/500</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error/404</location>
</error-page>
Yeni denetleyici oluştur
/**
* Error Controller. handles the calls for 404, 500 and 401 HTTP Status codes.
*/
@Controller
@RequestMapping(value = ErrorController.ERROR_URL, produces = MediaType.APPLICATION_XHTML_XML_VALUE)
public class ErrorController {
/**
* The constant ERROR_URL.
*/
public static final String ERROR_URL = "/error";
/**
* The constant TILE_ERROR.
*/
public static final String TILE_ERROR = "error.page";
/**
* Page Not Found.
*
* @return Home Page
*/
@RequestMapping(value = "/404", produces = MediaType.APPLICATION_XHTML_XML_VALUE)
public ModelAndView notFound() {
ModelAndView model = new ModelAndView(TILE_ERROR);
model.addObject("message", "The page you requested could not be found. This location may not be current.");
return model;
}
/**
* Error page.
*
* @return the model and view
*/
@RequestMapping(value = "/500", produces = MediaType.APPLICATION_XHTML_XML_VALUE)
public ModelAndView errorPage() {
ModelAndView model = new ModelAndView(TILE_ERROR);
model.addObject("message", "The page you requested could not be found. This location may not be current, due to the recent site redesign.");
return model;
}
}
Çünkü aynı şeyi yapmanın en az on yoluna sahip olmak her zaman iyidir:
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class Something {
@RequestMapping("/path")
public ModelAndView somethingPath() {
return new ModelAndView("/", HttpStatus.NOT_FOUND);
}
}