Я нашел, что все выше всего найдено ['a', 'b', 'd'] как подсловитель ['a', 'b', 'c', 'e', 'd'], который может быть неверным, несмотря на то, что все элементы подсписчика присутствуют в списке. Поэтому, чтобы поддерживать порядок, и я придумал:
def sublist4(sublist,lst):
#Define an temp array to populate
sub_list=[]
comparable_sublist=[]
#Define two constants to iterate in the while loop
i=0
k=0
#Loop the length of lst
while i < len(lst):
#If the element is in the sublist append to temp array,
if k < len(sublist) and lst[i] == sublist[k]:
sub_list.append(lst[i])
#set a comparable array to the value of temp array
comparable_sublist = sub_list
k += 1
#If the comparable array is the same as the sublist, break
if len(comparable_sublist) == len(sublist):
break
#If the element is not in the sublist, reset temp array
else:
sub_list = []
i += 1
return comparable_sublist == sublist
Хотя это не очень эффективно для памяти, я нахожу, что он отлично работает с небольшими списками.
Начиная с весны 3.1, лучший способ для создания Location - использовать параметр UriComponentBuilder
и установить его в возвращаемое значение ResponseEntity
. UriComponentBuilder
знает о контексте и манипулирует относительными путями:
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createCustomer(UriComponentsBuilder b) {
UriComponents uriComponents =
b.path("/customers/{id}").buildAndExpand(id);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(uriComponents.toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
Начиная с версии 4.1 вы можете сделать его еще короче
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createCustomer(UriComponentsBuilder b) {
UriComponents uriComponents =
b.path("/customers/{id}").buildAndExpand(id);
return ResponseEntity.created(uriComponents.toUri()).build();
}
Благодаря Дитеру Хубау за указание на это.
Согласно: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30
Следует использовать абсолютный URI:
Location = "Location" ":" absoluteURI
И URI следует правильно экранировать:
Это старый вопрос, но вот что вы можете сделать, если хотите, чтобы Spring действительно создала для вас URI.
@RestController
@RequestMapping("/api/v1")
class JobsController {
@PostMapping("/jobs")
fun createJob(@RequestParam("use-gpu") useGPU: Boolean?): ResponseEntity<Unit> {
val headers = HttpHeaders()
val jobId = "TBD id"
headers.location =
MvcUriComponentsBuilder
.fromMethodName(JobsController::class.java, "getJob", jobId)
.buildAndExpand(jobId)
.toUri()
return ResponseEntity(headers, HttpStatus.CREATED)
}
@GetMapping("/job/{jobId}")
fun getJob(@PathVariable jobId: String) = ... // fetch job
}
В этом примере (который написан на Kotlin, но похож на Java), базовый URI равен /api/v1
(определен в верхней части класса). Использование вызова MvcUriComponentsBuilder.fromMethodName
позволяет Spring определить правильный полный URI. (MvcUriComponentsBuilder
был добавлен в 4.0).
Следующий пример взят из весеннего учебного пособия:
@RequestMapping(method = RequestMethod.POST)
ResponseEntity<?> add(@PathVariable String userId, @RequestBody Bookmark input) {
this.validateUser(userId);
return this.accountRepository
.findByUsername(userId)
.map(account -> {
Bookmark result = bookmarkRepository.save(new Bookmark(account,
input.uri, input.description));
URI location = ServletUriComponentsBuilder
.fromCurrentRequest().path("/{id}")
.buildAndExpand(result.getId()).toUri();
return ResponseEntity.created(location).build();
})
.orElse(ResponseEntity.noContent().build());
}
Обратите внимание, что следующее вычислит путь контекста (URI), чтобы вы избежали дублирования кода и сделали ваше приложение более переносимым:
ServletUriComponentsBuilder
.fromCurrentRequest().path("/{id}")
Ваш подход кажется нормальным, но чтобы сохранить его в чистоте, вы можете поместить код в пользовательский HandlerInterceptor
, который срабатывает только при наличии HTTP 201, например.
См. здесь для получения дополнительной информации.