যখন স্প্রিং RESTful অ্যাপ্লিকেশনগুলির জন্য রেসপন্সএনটিটি <টি> এবং @ রিস্টকন্ট্রোলার ব্যবহার করুন


163

আমি এমভিসি এবং রেস্টের সাথে একত্রে স্প্রিং ফ্রেমওয়ার্ক 4.0.7 নিয়ে কাজ করছি

আমি এর সাথে শান্তিতে কাজ করতে পারি:

  • @Controller
  • ResponseEntity<T>

উদাহরণ স্বরূপ:

@Controller
@RequestMapping("/person")
@Profile("responseentity")
public class PersonRestResponseEntityController {

পদ্ধতি সহ (কেবল তৈরি করতে)

@RequestMapping(value="/", method=RequestMethod.POST)
public ResponseEntity<Void> createPerson(@RequestBody Person person, UriComponentsBuilder ucb){
    logger.info("PersonRestResponseEntityController  - createPerson");
    if(person==null)
        logger.error("person is null!!!");
    else
        logger.info("{}", person.toString());

    personMapRepository.savePerson(person);
    HttpHeaders headers = new HttpHeaders();
    headers.add("1", "uno");
    //http://localhost:8080/spring-utility/person/1
    headers.setLocation(ucb.path("/person/{id}").buildAndExpand(person.getId()).toUri());

    return new ResponseEntity<>(headers, HttpStatus.CREATED);
}

কিছু ফিরে

@RequestMapping(value="/{id}", method=RequestMethod.GET)
public ResponseEntity<Person> getPerson(@PathVariable Integer id){
    logger.info("PersonRestResponseEntityController  - getPerson - id: {}", id);
    Person person = personMapRepository.findPerson(id);
    return new ResponseEntity<>(person, HttpStatus.FOUND);
}

ঠিকভাবে কাজ করে

আমি এটি দিয়েও করতে পারি :

  • @RestController(আমি জানি এটি @Controller+ এর সমান @ResponseBody)
  • @ResponseStatus

উদাহরণ স্বরূপ:

@RestController
@RequestMapping("/person")
@Profile("restcontroller")
public class PersonRestController {

পদ্ধতি সহ (কেবল তৈরি করতে)

@RequestMapping(value="/", method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void createPerson(@RequestBody Person person, HttpServletRequest request, HttpServletResponse response){
    logger.info("PersonRestController  - createPerson");
    if(person==null)
        logger.error("person is null!!!");
    else
        logger.info("{}", person.toString());

    personMapRepository.savePerson(person);
    response.setHeader("1", "uno");

    //http://localhost:8080/spring-utility/person/1
    response.setHeader("Location", request.getRequestURL().append(person.getId()).toString());
}

কিছু ফিরে

@RequestMapping(value="/{id}", method=RequestMethod.GET)
@ResponseStatus(HttpStatus.FOUND)
public Person getPerson(@PathVariable Integer id){
    logger.info("PersonRestController  - getPerson - id: {}", id);
    Person person = personMapRepository.findPerson(id);
    return person;
}

আমার প্রশ্নগুলি হ'ল:

  1. যখন কোনও দৃ reason় কারণে বা নির্দিষ্ট দৃশ্যের জন্য এক বিকল্প অপরটির চেয়ে বাধ্যতামূলকভাবে ব্যবহার করা উচিত
  2. যদি (1) কিছু যায় আসে না, তবে কোন পদ্ধতির পরামর্শ দেওয়া হয়েছে এবং কেন।

উত্তর:


213

ResponseEntityসম্পূর্ণ HTTP প্রতিক্রিয়া উপস্থাপন বোঝানো হয়। আপনি এটিতে যে কোনও কিছু নিয়ন্ত্রণ করতে পারেন: স্থিতি কোড, শিরোনাম এবং বডি।

@ResponseBodyHTTP প্রতিক্রিয়া সংস্থার জন্য চিহ্নিতকারী এবং HTTP প্রতিক্রিয়াটির @ResponseStatusস্থিতি কোড ঘোষণা করে।

@ResponseStatusখুব নমনীয় নয়। এটি সম্পূর্ণ পদ্ধতি চিহ্নিত করে তাই আপনার নিশ্চিত হওয়া উচিত যে আপনার হ্যান্ডলার পদ্ধতিটি সর্বদা একইভাবে আচরণ করবে। এবং আপনি এখনও শিরোনাম সেট করতে পারবেন না। আপনার দরকার HttpServletResponseবা একটি HttpHeadersপ্যারামিটার দরকার।

মূলত, ResponseEntityআপনাকে আরও কিছু করতে দেয়।


6
তৃতীয় পর্যবেক্ষণ সম্পর্কে ভাল পয়েন্ট। আপনাকে ধন্যবাদ ... এবং আমি ResponseEntityএটি সম্পর্কে আরও ভেবেছি , এটি আরও নমনীয়। শুধু আমি সন্দেহ সম্পর্কে ছিল @RestController। আপনাকে ধন্যবাদ
ম্যানুয়েল জর্ডান

55

সটোরিওস ডেলিমনোলিস থেকে উত্তরটি সম্পূর্ণ করতে।

এটি সত্য যে ResponseEntityআপনাকে আরও নমনীয়তা দেয় তবে বেশিরভাগ ক্ষেত্রে আপনার এটির প্রয়োজন হবে না এবং আপনি ResponseEntityআপনার নিয়ামকের যে কোনও জায়গায় এইগুলি শেষ করতে পারেন যাতে এটি পড়া এবং বুঝতে অসুবিধা হয়।

আপনি যদি ত্রুটিগুলির (যেমন পাওয়া যায় না, বিবাদ ইত্যাদি) বিশেষ ক্ষেত্রে পরিচালনা করতে চান তবে HandlerExceptionResolverআপনি আপনার বসন্তের কনফিগারেশনে একটি যুক্ত করতে পারেন । সুতরাং আপনার কোডে, আপনি কেবল একটি নির্দিষ্ট ব্যতিক্রম ছুঁড়ে NotFoundExceptionফেলেছেন (উদাহরণস্বরূপ) এবং আপনার হ্যান্ডলারে কী করবেন তা স্থির করুন (HTTP স্থিতি 404 এ সেট করা), নিয়ন্ত্রণকারী কোডটি আরও স্পষ্ট করে তুলেছে।


5
আপনার দৃষ্টিকোণটি (@) এক্সসেপশনহ্যান্ডলারের সাথে বৈধ। মুল বক্তব্যটি: আপনি যদি সমস্ত পদ্ধতিতে একটি পদ্ধতিতে হ্যান্ডেল করতে চান (চেষ্টা করুন / ধরুন) তবে আপনি যদি পুনরায় ব্যবহার করতে চান তবে ব্যতিক্রম হ্যান্ডলিং (@) এক্সেসপেশন হ্যান্ডলারের জন্য অনেকগুলি (@) রিকোয়েস্টম্যাপিং ভাল ফিট করে। আমি এইচটিপিপিটিটি পছন্দ করি কারণ আমি এইচটিপিএইচইডারদের সাথেও কাজ করতে সক্ষম।
ম্যানুয়েল জর্ডান

46

অফিসিয়াল ডকুমেন্টেশন অনুসারে: @ রিস্টকন্ট্রোলার টিকা দিয়ে আরএসটি নিয়ন্ত্রণকারী তৈরি করা হচ্ছে

@ রিস্টকন্ট্রোলার হ'ল স্টেরিওটাইপ টিকা that এর চেয়েও বেশি, এটি আপনার নিয়ামককে আরও অর্থ দেয় এবং ভবিষ্যতের কাঠামোর প্রকাশে অতিরিক্ত শব্দার্থতাকে বহন করতে পারে।

মনে হচ্ছে যে এটি ব্যবহার করতে সেরা @RestControllerস্বচ্ছতার জন্য, কিন্তু আপনি করতে পারেন মেশা সঙ্গে এটি ResponseEntityনমনীয়তার জন্য প্রয়োজন হলে ( সরকারী টিউটোরিয়াল অনুযায়ী এবং কোড এখানে এবং নিশ্চিত যে আমার প্রশ্ন )।

উদাহরণ স্বরূপ:

@RestController
public class MyController {

    @GetMapping(path = "/test")
    @ResponseStatus(HttpStatus.OK)
    public User test() {
        User user = new User();
        user.setName("Name 1");

        return user;
    }

}

হিসাবে একই:

@RestController
public class MyController {

    @GetMapping(path = "/test")
    public ResponseEntity<User> test() {
        User user = new User();
        user.setName("Name 1");

        HttpHeaders responseHeaders = new HttpHeaders();
        // ...
        return new ResponseEntity<>(user, responseHeaders, HttpStatus.OK);
    }

}

এইভাবে, আপনি ResponseEntityপ্রয়োজন হলে কেবল সংজ্ঞা দিতে পারেন ।

হালনাগাদ

আপনি এটি ব্যবহার করতে পারেন:

    return ResponseEntity.ok().headers(responseHeaders).body(user);

যদি আমরা পদ্ধতিটিতে @ রেসপনস স্ট্যাটাস (এইচটিপিস্ট্যাটাস.ওকে) যোগ করেছি তবে কী পদ্ধতিটি নতুন রেসপন্স এনটিটিটি <> (ব্যবহারকারী, প্রতিক্রিয়াহাইডার্স, এইচটিপিস্ট্যাটাস.নোT_ফাউন্ড) ফেরত দেয়; আমি কেবল ভাবছি যে @ রেসপন্স স্ট্যাটাস প্রতিক্রিয়া কোডটি আরও সংশোধন করবে কিনা।
প্রতাপী হেমন্ত প্যাটেল

4
@ হেমন্ত মনে @ResponseStatus(HttpStatus.OK)হয় আপনি ফিরে এলে তা উপেক্ষা করা হবে ResponseEntity<>(user, responseHeaders, HttpStatus.NOT_FOUND)। HTTP প্রতিক্রিয়া হয়404
Danail

রেসপন্সস্ট্যাটাসের জাভাডোকস থেকে। যখন হ্যান্ডলার পদ্ধতিটি চালিত হয় এবং means @ কোড রিসপন্সটিটি} বা c @ কোড "পুনঃনির্দেশ:" like এর মতো অন্যান্য উপায়ে সেট করা স্থিতির তথ্য ওভাররাইড করে তখন স্থিতি কোডটি HTTP প্রতিক্রিয়াতে প্রয়োগ করা হয়}
vzhemevko

14

একটি যথাযথ REST এপিআই এর প্রতিক্রিয়াতে নীচের উপাদান থাকা উচিত

  1. স্থিতি কোড
  2. প্রতিক্রিয়া বডি
  3. পরিবর্তিত ছিল এমন সংস্থার অবস্থান (উদাহরণস্বরূপ, যদি কোনও উত্স তৈরি করা হয়, ক্লায়েন্টটি সেই অবস্থানটির url জানতে আগ্রহী হবে)

রেসপন্সটিটির মূল উদ্দেশ্যটি 3 বিকল্পটি সরবরাহ করা ছিল, বাকী বিকল্পগুলি রেসপন্স এন্টিটি ছাড়াই অর্জন করা যেতে পারে।

সুতরাং আপনি যদি সংস্থানটির অবস্থান সরবরাহ করতে চান তবে রেসপন্সএন্টিটি ব্যবহার করা আরও ভাল হবে অন্যথায় এড়ানো যায়।

একটি উদাহরণ বিবেচনা করুন যেখানে উল্লিখিত সমস্ত বিকল্পগুলি সরবরাহ করতে একটি এপিআই পরিবর্তন করা হয়েছে

// Step 1 - Without any options provided
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public @ResponseBody Spittle spittleById(@PathVariable long id) {
  return spittleRepository.findOne(id);
}

// Step 2- We need to handle exception scenarios, as step 1 only caters happy path.
@ExceptionHandler(SpittleNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Error spittleNotFound(SpittleNotFoundException e) {
  long spittleId = e.getSpittleId();
  return new Error(4, "Spittle [" + spittleId + "] not found");
}

// Step 3 - Now we will alter the service method, **if you want to provide location**
@RequestMapping(
    method=RequestMethod.POST
    consumes="application/json")
public ResponseEntity<Spittle> saveSpittle(
    @RequestBody Spittle spittle,
    UriComponentsBuilder ucb) {

  Spittle spittle = spittleRepository.save(spittle);
  HttpHeaders headers = new HttpHeaders();
  URI locationUri =
  ucb.path("/spittles/")
      .path(String.valueOf(spittle.getId()))
      .build()
      .toUri();
  headers.setLocation(locationUri);
  ResponseEntity<Spittle> responseEntity =
      new ResponseEntity<Spittle>(
          spittle, headers, HttpStatus.CREATED)
  return responseEntity;
}

// Step4 - If you are not interested to provide the url location, you can omit ResponseEntity and go with
@RequestMapping(
    method=RequestMethod.POST
    consumes="application/json")
@ResponseStatus(HttpStatus.CREATED)
public Spittle saveSpittle(@RequestBody Spittle spittle) {
  return spittleRepository.save(spittle);
}

উত্স - অ্যাকশন বসন্ত

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