উত্তর:
বসন্ত 3.0.০ থেকে আপনি এনেটেশন সহ ঘোষিত একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারেন @ResponseStatus
:
@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
, নামযুক্ত ব্যতিক্রম শ্রেণির পুরো গুচ্ছকে সংজ্ঞায়িত করেছেন, প্রতিটি তাদের নিজস্ব রয়েছে @ResponseStatus
। এইভাবে, আপনি এইচটিটিপি স্থিতি কোডের বিশদ থেকে আপনার নিয়ামক কোডটি ডিকুয়াল করেন।
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason="Your reason")
ResourceNotFound.fillInStackTrace()
খালি বাস্তবায়নটি ওভাররাইড করা ভাল ধারণা ।
স্প্রিং 5.0 থেকে শুরু করে আপনার অতিরিক্ত ব্যতিক্রমগুলি তৈরি করার প্রয়োজন হবে না:
throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");
এছাড়াও, আপনি একাধিক দৃশ্যের সাথে অন্তর্নির্মিত ব্যতিক্রম কভার করতে পারেন এবং আপনার আরও নিয়ন্ত্রণ রাখতে পারেন।
আরো দেখুন:
আপনার পদ্ধতির স্বাক্ষরটি পুনরায় লিখুন যাতে এটি HttpServletResponse
প্যারামিটার হিসাবে গ্রহণ করে , যাতে আপনি setStatus(int)
এটিতে কল করতে পারেন ।
setStatus(int)
জাভাডোক নিম্নরূপ বলেছেন: যদি এই পদ্ধতিটি ত্রুটি কোড সেট করতে ব্যবহৃত হয় তবে ধারকটির ত্রুটি পৃষ্ঠা প্রক্রিয়াটি ট্রিগার হবে না। যদি কোনও ত্রুটি হয় এবং কলার ওয়েব অ্যাপ্লিকেশনে সংজ্ঞায়িত ত্রুটি পৃষ্ঠাটি চাওয়াতে চান তবে sendError
তার পরিবর্তে অবশ্যই ব্যবহার করা উচিত।
আমি উল্লেখ করতে চাই যে স্প্রিং দ্বারা সরবরাহিত ডিফল্ট হিসাবে 404 এর ব্যতিক্রম (কেবলমাত্র নয়)। বিশদ জন্য স্প্রিং ডকুমেন্টেশন দেখুন । সুতরাং আপনার যদি নিজের ব্যতিক্রম প্রয়োজন না হয় তবে আপনি কেবল এটি করতে পারেন:
@RequestMapping(value = "/**", method = RequestMethod.GET)
public ModelAndView show() throws NoSuchRequestHandlingMethodException {
if(something == null)
throw new NoSuchRequestHandlingMethodException("show", YourClass.class);
...
}
@PathVariable
আমার দৃষ্টিকোণ থেকে হ্যান্ডলিংয়ের জন্য কোনও অনুরোধ নেই। আপনি কি মনে করেন যে এটির সাথে মন্তব্য করা নিজস্ব ব্যতিক্রমটি ব্যবহার করা আরও ভাল / ক্লিনার @ResponseStatus(value = HttpStatus.NOT_FOUND)
?
বসন্ত 3.0.০.২ থেকে আপনি নিয়ন্ত্রকের পদ্ধতির ফলাফল হিসাবে প্রতিক্রিয়া <<< ফিরে আসতে পারেন :
@RequestMapping.....
public ResponseEntity<Object> handleCall() {
if (isFound()) {
// do what you want
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
(রেসপন্সটিটিটি <টি> @ রেসপন্সবডি টীকাটির চেয়ে আরও নমনীয় - অন্য একটি প্রশ্ন দেখুন )
আপনি আপনার ব্যতিক্রমগুলি পরিচালনা করতে @ নিয়ন্ত্রণকারী অ্যাডভাইসটি ব্যবহার করতে পারেন, @ নিয়ন্ত্রণকারী অ্যাডভাইস টিকা দেওয়া ক্লাসটি সমস্ত পরিচিত নিয়ন্ত্রণকারীদের সহায়তা করবে default
সুতরাং আপনার যখন কোনও কন্ট্রোলার 404 ত্রুটি ছুড়ে মারবে তখন এটি ডাকা হবে।
নিম্নলিখিত মত:
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND) // 404
@ExceptionHandler(Exception.class)
public void handleNoTFound() {
// Nothing to do
}
}
এবং নীচের মত আপনার ওয়েব.এক্সএমএলে এই 404 টি প্রতিক্রিয়ার ত্রুটিটি ম্যাপ করুন:
<error-page>
<error-code>404</error-code>
<location>/Error404.html</location>
</error-page>
আশা করি এইটি কাজ করবে .
যদি আপনার কন্ট্রোলার পদ্ধতি ফাইল হ্যান্ডলিংয়ের মতো কিছু ResponseEntity
হয় তবে খুব কার্যকর:
@Controller
public class SomeController {
@RequestMapping.....
public ResponseEntity handleCall() {
if (isFound()) {
return new ResponseEntity(...);
}
else {
return new ResponseEntity(404);
}
}
}
চিহ্নিত উত্তরটি সঠিক হলেও ব্যতিক্রম ছাড়াই এটি অর্জনের একটি উপায় রয়েছে। পরিষেবাটি Optional<T>
অনুসন্ধান করা অবজেক্টটি ফিরে আসবে এবং এটি HttpStatus.OK
যদি পাওয়া যায় তবে এটি ম্যাপ করা হবে এবং খালি থাকলে 404 এ।
@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);
}
}
আমি এই জাতীয় HttpClientErrorException নিক্ষেপ করার পরামর্শ দিই
@RequestMapping(value = "/sample/")
public void sample() {
if (somethingIsWrong()) {
throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
}
}
আপনার অবশ্যই মনে রাখতে হবে সার্ভলেট আউটপুট স্ট্রিমে কোনও কিছু লেখার আগে এটি করা যেতে পারে।
Whitelabel Error Page \n .... \n There was an unexpected error (type=Internal Server Error, status=500). \n 404 This is your not found error
এটি কিছুটা দেরি হয়ে গেছে, তবে আপনি যদি স্প্রিং ডেটা REST ব্যবহার করেন তবে ইতিমধ্যে org.springframework.data.rest.webmvc.ResourceNotFoundException
এটি @ResponseStatus
টীকাও ব্যবহার করে । আর কোনও কাস্টম রানটাইম ব্যতিক্রম তৈরি করার দরকার নেই।
এছাড়াও আপনি যদি আপনার কন্ট্রোলার থেকে 404 স্থিতি ফিরে আসতে চান তবে আপনার এটি করা দরকার
@RequestMapping(value = "/somthing", method = RequestMethod.POST)
@ResponseBody
public HttpStatus doSomthing(@RequestBody String employeeId) {
try{
return HttpStatus.OK;
}
catch(Exception ex){
return HttpStatus.NOT_FOUND;
}
}
এটি করার দ্বারা আপনি যখন আপনার নিয়ামক থেকে 404 ফেরত চান তখন আপনি 404 ত্রুটি পাবেন।
কেবল ত্রুটি কোড এবং 404 ত্রুটি পৃষ্ঠা যুক্ত করতে আপনি ওয়েব.এক্সএমএল ব্যবহার করতে পারেন। তবে নিশ্চিত হয়ে নিন যে 404 ত্রুটি পৃষ্ঠাটি অবশ্যই ওয়েবে-আইএনএফের অধীনে সনাক্ত করা উচিত নয়।
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
এটি করার সহজতম উপায় এটির কিছুটা সীমাবদ্ধতা রয়েছে। মনে করুন আপনি যদি এই পৃষ্ঠার জন্য একই স্টাইল যুক্ত করতে চান যা আপনি অন্যান্য পৃষ্ঠা যুক্ত করেছেন। এইভাবে আপনি এটি করতে পারবেন না। আপনি ব্যবহার করতে হবে@ResponseStatus(value = HttpStatus.NOT_FOUND)
HttpServletResponse#sendError(HttpServletResponse.SC_NOT_FOUND); return null;
এটি নিয়ামক কোড থেকে বিবেচনা করুন । এখন বাইরে থেকে প্রতিক্রিয়া সাধারণ 404 এর চেয়ে আলাদা নয় যা কোনও নিয়ামককে আঘাত করে নি hit
সেটিং সহ ওয়েব.এক্সএমএল কনফিগার করুন
<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>
নতুন নিয়ামক তৈরি করুন
/**
* 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;
}
}
কারণ সর্বদা একই জিনিস করার কমপক্ষে দশটি উপায় থাকা ভাল:
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);
}
}