স্প্রিং-এমভিসি নিয়ামক 4040 ট্রিগার?


193

404 ট্রিগার করার জন্য আমি কীভাবে একটি স্প্রিং 3.0 কন্ট্রোলার পেতে পারি ?

আমার কাছে নিয়ামক সহ @RequestMapping(value = "/**", method = RequestMethod.GET)কিছু ইউআরএল অ্যাক্সেস করার নিয়ন্ত্রক রয়েছে, আমি চাই যে ধারকটি 404 নিয়ে আসে।

উত্তর:


326

বসন্ত 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(); 
        }
    }
}

2
মজাদার. আপনি কোন HTTPStatus নিক্ষেপ সাইটে ব্যবহার করবেন তা নির্দিষ্ট করতে পারবেন (যেমন এটি ব্যতিক্রম শ্রেণিতে সংকলিত হয়নি)?
ম্যাট বি

1
@ ম্যাটটিবি: আমি মনে করি যে মূল বক্তব্যটি হ'ল আপনি দৃ strongly়-টাইপযুক্ত @ResponseStatus, নামযুক্ত ব্যতিক্রম শ্রেণির পুরো গুচ্ছকে সংজ্ঞায়িত করেছেন, প্রতিটি তাদের নিজস্ব রয়েছে @ResponseStatus। এইভাবে, আপনি এইচটিটিপি স্থিতি কোডের বিশদ থেকে আপনার নিয়ামক কোডটি ডিকুয়াল করেন।
skaffman

9
ত্রুটি সম্পর্কে আরও বিবরণযুক্ত কোনও শরীরে ফিরে যাওয়ার পক্ষে কি এটি বাড়ানো যেতে পারে?
টম

7
@ টম:@ResponseStatus(value = HttpStatus.NOT_FOUND, reason="Your reason")
নেলগুন

6
আপনি যদি কেবলমাত্র প্রবাহ নিয়ন্ত্রণের জন্য এই রিসোর্সনটফাউন্ড ব্যতিক্রমটি ব্যবহার করেন তবে ResourceNotFound.fillInStackTrace()খালি বাস্তবায়নটি ওভাররাইড করা ভাল ধারণা ।
রাল্ফ

38

স্প্রিং 5.0 থেকে শুরু করে আপনার অতিরিক্ত ব্যতিক্রমগুলি তৈরি করার প্রয়োজন হবে না:

throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");

এছাড়াও, আপনি একাধিক দৃশ্যের সাথে অন্তর্নির্মিত ব্যতিক্রম কভার করতে পারেন এবং আপনার আরও নিয়ন্ত্রণ রাখতে পারেন।

আরো দেখুন:


36

আপনার পদ্ধতির স্বাক্ষরটি পুনরায় লিখুন যাতে এটি HttpServletResponseপ্যারামিটার হিসাবে গ্রহণ করে , যাতে আপনি setStatus(int)এটিতে কল করতে পারেন ।

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-arguments


8
এটি কেবলমাত্র সঠিক উত্তর যদি কেউ HTTP অনুরোধকারীকে বলার কোনও উপায় সন্ধান করে তবে তারা ভুল করতে পেরে প্রোড অপস দলটিকে বন্যা না করে তারা কিছুটা ব্যতিক্রম সংশোধন করতে পারে না।
অ্যালেক্স আর

4
setStatus(int)জাভাডোক নিম্নরূপ বলেছেন: যদি এই পদ্ধতিটি ত্রুটি কোড সেট করতে ব্যবহৃত হয় তবে ধারকটির ত্রুটি পৃষ্ঠা প্রক্রিয়াটি ট্রিগার হবে না। যদি কোনও ত্রুটি হয় এবং কলার ওয়েব অ্যাপ্লিকেশনে সংজ্ঞায়িত ত্রুটি পৃষ্ঠাটি চাওয়াতে চান তবে sendErrorতার পরিবর্তে অবশ্যই ব্যবহার করা উচিত।
ফিলিপ জিওসিফি

@ অ্যালেক্সআর পরিচালিত ব্যতিক্রমগুলি অপস দলকে প্লাবিত করা উচিত নয়। যদি সেগুলি হয় তবে লগিংটি ভুলভাবে করা হচ্ছে।
রায়েডওয়াল্ড

25

আমি উল্লেখ করতে চাই যে স্প্রিং দ্বারা সরবরাহিত ডিফল্ট হিসাবে 404 এর ব্যতিক্রম (কেবলমাত্র নয়)। বিশদ জন্য স্প্রিং ডকুমেন্টেশন দেখুন । সুতরাং আপনার যদি নিজের ব্যতিক্রম প্রয়োজন না হয় তবে আপনি কেবল এটি করতে পারেন:

 @RequestMapping(value = "/**", method = RequestMethod.GET)
 public ModelAndView show() throws NoSuchRequestHandlingMethodException {
    if(something == null)
         throw new NoSuchRequestHandlingMethodException("show", YourClass.class);

    ...

  }

11
এটি একটি নির্দিষ্ট কেসের জন্য বোঝানো দেখায় - যখন বসন্ত কোনও হ্যান্ডলার খুঁজে পায় না। প্রশ্নে ক্ষেত্রে যখন বসন্ত পারেন একটি হ্যান্ডলার খুঁজে, কিন্তু ব্যবহারকারী অন্য কারণ জন্য একটি 404 আসতে চায়।
রায় ট্রুইলোভ

2
হ্যান্ডলার পদ্ধতির জন্য আমার আলর ম্যাপিংটি গতিশীল হলে আমি এটি ব্যবহার করছি। যখন সত্তাটির ভিত্তিতে অস্তিত্ব নেই তখন @PathVariableআমার দৃষ্টিকোণ থেকে হ্যান্ডলিংয়ের জন্য কোনও অনুরোধ নেই। আপনি কি মনে করেন যে এটির সাথে মন্তব্য করা নিজস্ব ব্যতিক্রমটি ব্যবহার করা আরও ভাল / ক্লিনার @ResponseStatus(value = HttpStatus.NOT_FOUND) ?
michal.kreuzman

1
আপনার ক্ষেত্রে এটি দুর্দান্ত শোনাচ্ছে, তবে আমি জানি না যে আপনি যে সমস্ত ক্ষেত্রে প্রয়োজনীয় ব্যতিক্রম প্রয়োজন সেখানে পরিচালনা করতে আপনার দেওয়া লিঙ্কটিতে পাওয়া ব্যতিক্রমগুলি সুপারিশ করব - কখনও কখনও আপনার নিজের হওয়া উচিত।
রায় ট্রুইলোভ

ওয়েল, স্প্রিং একটি ব্যতিক্রম এবং কেবল ৪৪৪ এর জন্য একটি সরবরাহ করেছে They তাদের এটির নাম রাখা উচিত 404 অনুভূতি বা একটি তৈরি করা উচিত। কিন্তু এটা এখন, আমি মনে করি এটা এই নিক্ষেপ যখনই আপনি কোনো 404. প্রয়োজন ঠিক আছে
autra

ভাল, প্রযুক্তিগতভাবে এটি ঠিক আছে - আপনি 404 স্থিতির শিরোনাম প্রেরণ করবেন। তবে স্বয়ংক্রিয় ত্রুটি বার্তা - প্রতিক্রিয়া সামগ্রী - "নামের সাথে কোনও অনুরোধ পরিচালনা করার পদ্ধতি ..." যা সম্ভবত আপনি ব্যবহারকারীর কাছে দেখাতে চান এমন কিছু নয়।
ওলি

24

বসন্ত 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);
    }
}

(রেসপন্সটিটিটি <টি> @ রেসপন্সবডি টীকাটির চেয়ে আরও নমনীয় - অন্য একটি প্রশ্ন দেখুন )


2
অবশ্যই নমনীয় তবে ঘোষিত প্রোগ্রামিংয়ের সুবিধাগুলি পরাস্ত করে
রোহানগরওয়াল

3
আপনি যদি সেন্ট্রি বা পিআরডির অনুরূপ ব্যবহার করে থাকেন এবং কোনও ত্রুটি না করে এমন কোনও ত্রুটিগুলি দিয়ে এটি স্প্যাম করতে না চান তবে এই অ-ব্যতিক্রমী পরিস্থিতির ব্যতিক্রম ব্যতীত ব্যবহারের তুলনায় এই সমাধানটি আরও ভাল।
টোবিয়াস হারমান

কীভাবে শরীরকে পপুল করবেন তা ভুলে যাবেন না (আপনার আসল বস্তুর সাথে)। জেনেরিক "অবজেক্ট" উদাহরণ: অবজেক্ট রিটার্ন আইটেমবডি = নতুন অবজেক্ট (); রিটার্ন রেসপন্সইটিটি.স্ট্যাটাস (এইচটিটিপিস্ট্যাটাস.ওকে) .বডি (রিটার্নআইটেমবডি);
গ্রানাডা কোডার

16

আপনি আপনার ব্যতিক্রমগুলি পরিচালনা করতে @ নিয়ন্ত্রণকারী অ্যাডভাইসটি ব্যবহার করতে পারেন, @ নিয়ন্ত্রণকারী অ্যাডভাইস টিকা দেওয়া ক্লাসটি সমস্ত পরিচিত নিয়ন্ত্রণকারীদের সহায়তা করবে 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>

আশা করি এইটি কাজ করবে .


2
আপনি 404 স্থিতি কোড সহ ব্যতিক্রম (এবং উপক্লাস) টাইপের ব্যতিক্রম ম্যাপ করেছেন। আপনি কি কখনও ভেবেছিলেন অভ্যন্তরীণ সার্ভারের ত্রুটি রয়েছে? আপনি কীভাবে আপনার গ্লোবালকন্ট্রোলার এক্সপেকশনহ্যান্ডলারের পরিচালনা করবেন?
রোহনগরওয়াল

এটি আরএসটি নিয়ন্ত্রণকারীদের জন্য কাজ করে না, একটি খালি প্রতিক্রিয়া দেয়।
rustyx

10

যদি আপনার কন্ট্রোলার পদ্ধতি ফাইল হ্যান্ডলিংয়ের মতো কিছু ResponseEntityহয় তবে খুব কার্যকর:

@Controller
public class SomeController {
    @RequestMapping.....
    public ResponseEntity handleCall() {
        if (isFound()) {
            return new ResponseEntity(...);
        }
        else {
            return new ResponseEntity(404);
        }
    }
}

9

চিহ্নিত উত্তরটি সঠিক হলেও ব্যতিক্রম ছাড়াই এটি অর্জনের একটি উপায় রয়েছে। পরিষেবাটি 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); 
    }

}

আমি এই পদ্ধতিটি সাধারণভাবে পছন্দ করি তবে বিকল্পগুলি ব্যবহার করে মাঝে মাঝে একটি অ্যান্টি-প্যাটার্ন হওয়া যায়। সংগ্রহগুলি ফেরত দেওয়ার সময় জটিল হয়ে ওঠে।
jfzr

7

আমি এই জাতীয় HttpClientErrorException নিক্ষেপ করার পরামর্শ দিই

@RequestMapping(value = "/sample/")
public void sample() {
    if (somethingIsWrong()) {
        throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
    }
}

আপনার অবশ্যই মনে রাখতে হবে সার্ভলেট আউটপুট স্ট্রিমে কোনও কিছু লেখার আগে এটি করা যেতে পারে।


4
এই ব্যতিক্রমটি স্প্রিং এইচটিটিপি ক্লায়েন্ট দ্বারা ছুঁড়ে দেওয়া হয়েছে। স্প্রিং এমভিসি মনে করে যে ব্যতিক্রমটি স্বীকৃতি দেয় না। আপনি কোন বসন্ত সংস্করণ ব্যবহার করছেন? আপনি কি ব্যতিক্রমটি দিয়ে 404 পাচ্ছেন?
এডুয়ার্ডো

1
এর ফলে স্প্রিং বুট ফিরে আসে:Whitelabel Error Page \n .... \n There was an unexpected error (type=Internal Server Error, status=500). \n 404 This is your not found error
পাতলা

এটি কোনও HTTP ক্লায়েন্টের জন্য একটি ব্যতিক্রম, কোনও নিয়ামকের পক্ষে নয়। সুতরাং নির্দিষ্ট প্রসঙ্গে এটি ব্যবহার করা অনুচিত।
অ্যালেক্সি

3

এটি কিছুটা দেরি হয়ে গেছে, তবে আপনি যদি স্প্রিং ডেটা REST ব্যবহার করেন তবে ইতিমধ্যে org.springframework.data.rest.webmvc.ResourceNotFoundException এটি @ResponseStatusটীকাও ব্যবহার করে । আর কোনও কাস্টম রানটাইম ব্যতিক্রম তৈরি করার দরকার নেই।


2

এছাড়াও আপনি যদি আপনার কন্ট্রোলার থেকে 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 ত্রুটি পাবেন।


0

কেবল ত্রুটি কোড এবং 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
ড্যারিল মাইলস

এটি একটি 404 কে ট্রিগার করে না, যদি এটি ঘটে তবে কেবল এটি পরিচালনা করে
অ্যালেক্স আর

0

সেটিং সহ ওয়েব.এক্সএমএল কনফিগার করুন

<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;
        }
}

0

কারণ সর্বদা একই জিনিস করার কমপক্ষে দশটি উপায় থাকা ভাল:

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);
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.