所以我使用Spring 5创建了以下rest API。
http://localhost:8080/restful-webservices/users/DtvQLbP5uUXaJr4y5n2yxch3BODQCd
{
"userId": "DtvQLbP5uUXaJr4y5n2yxch3BODQCd",
"firstName": "T",
"lastName": "T",
"email": "email1@gmail.com",
"addresses": [
{
"id": 158,
"addressId": "yRK81aJUn2Sfh4JSaWU4svr2YtWgZj",
"city": "Larissa",
"country": "Greece",
"streetName": "Iasonos 33",
"postalCode": "41223",
"type": "billing"
},
{
"id": 157,
"addressId": "ajyPnC75jQ2G5aqfDY4sqBYk5BUE9X",
"city": "Larissa",
"country": "Greece",
"streetName": "Palaiologou 11",
"postalCode": "41223",
"type": "shipping"
}
]
}
我可以更新用户的详细信息,但是现在我也想更新地址的详细信息。 http://localhost:8080/restful-webservices/users/DtvQLbP5uUXaJr4y5n2yxch3BODQCd/addresses/yRK81aJUn2Sfh4JSaWU4svr2YtWgZj
{
"addressId": "yRK81aJUn2Sfh4JSaWU4svr2YtWgZj",
"city": "Larissa",
"country": "Greece",
"streetName": "Iasonos 33",
"postalCode": "41223",
"type": "billing"
}
但是,我得到了这个
{
"timestamp": "2019-03-24T08:53:27.986+0000",
"message": "Missing URI template variable 'id' for method parameter of type String"
}
这是我的 AddressServiceImpl 类
@Service
public class AddressServiceImpl implements AddressService {
@Autowired
UserRepository userRepository;
@Autowired
AddressRepository addressRepository;
@Override
public List<AddressDTO> getAddresses(String userId) {
List<AddressDTO> returnValue = new ArrayList<>();
ModelMapper modelMapper = new ModelMapper();
UserEntity userEntity = userRepository.findByUserId(userId);
if(userEntity == null) return returnValue;
Iterable<AddressEntity> addresses = addressRepository.findAllByUserDetails(userEntity);
for(AddressEntity addressEntity : addresses){
returnValue.add(modelMapper.map(addressEntity, AddressDTO.class));
}
return returnValue;
}
@Override
public AddressDTO getAddress(String addressId) {
AddressDTO returnValue = null;
AddressEntity addressEntity = addressRepository.findByAddressId(addressId);
if(addressEntity != null){
returnValue = new ModelMapper().map(addressEntity, AddressDTO.class);
}
return returnValue;
}
@Override
public AddressDTO updateAddress(String addressId, AddressDTO address) {
AddressDTO returnValue = new AddressDTO();
AddressEntity addressEntity = addressRepository.findByAddressId(addressId);
if(addressEntity == null){
throw new UserServiceException(ErrorMessages.NO_RECORD_FOUND.getErrorMessage());
}
addressEntity.setCity(address.getCity());
addressEntity.setCountry(address.getCountry());
addressEntity.setPostalCode(address.getPostalCode());
addressEntity.setStreetName(address.getType());
AddressEntity updatedUserEntity = addressRepository.save(addressEntity);
BeanUtils.copyProperties(updatedUserEntity,returnValue);
return returnValue;
}
}
和我的控制器。
@RestController
@RequestMapping("users")
public class UserController {
@Autowired
UserService userService;
@Autowired
AddressService addressService;
@Autowired
AddressService addressesService;
@GetMapping(path = "/{id}",
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} )
public UserRest getUser(@PathVariable String id){
UserRest returnValue = new UserRest();
UserDto userDto = userService.getUserByUserId(id);
BeanUtils.copyProperties(userDto, returnValue);
return returnValue;
}
@PostMapping(
consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public UserRest createUser(@RequestBody UsersDetailsRequestModel userDetails) throws Exception{
UserRest returnValue = new UserRest();
if(userDetails.getFirstName().isEmpty()) throw new NullPointerException("The object is null");
// UserDto userDto = new UserDto();
// BeanUtils.copyProperties(userDetails,userDto);
ModelMapper modelMapper = new ModelMapper();
UserDto userDto = modelMapper.map(userDetails, UserDto.class);
UserDto createUser = userService.createUser(userDto);
// BeanUtils.copyProperties(createUser,returnValue);
returnValue = modelMapper.map(createUser, UserRest.class);
return returnValue;
}
@PutMapping(path = "/{id}",
consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public UserRest updateUser(@PathVariable String id, @RequestBody UsersDetailsRequestModel userDetails){
UserRest returnValue = new UserRest();
if(userDetails.getFirstName().isEmpty()) throw new NullPointerException("The object is null");
UserDto userDto = new UserDto();
BeanUtils.copyProperties(userDetails,userDto);
UserDto updatedUser = userService.updateUser(id, userDto);
BeanUtils.copyProperties(updatedUser,returnValue);
return returnValue;
}
@DeleteMapping(path = "/{id}", produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
public OperationStatusModel deleteUser(@PathVariable String id){
OperationStatusModel returnValue = new OperationStatusModel();
returnValue.setOperationName(RequestOperationName.DELETE.name());
userService.deleteUser(id);
returnValue.setOperationResult(RequestOperationStatus.SUCCESS.name());
return returnValue;
}
@GetMapping(produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
public List<UserRest> getUsers(@RequestParam(value="page", defaultValue = "0") int page,
@RequestParam(value="limit", defaultValue = "25") int limit){
List<UserRest> returnValue = new ArrayList<>();
List<UserDto> users = userService.getUsers(page,limit);
for(UserDto userDto : users){
UserRest userModel = new UserRest();
BeanUtils.copyProperties(userDto, userModel);
returnValue.add(userModel);
}
return returnValue;
}
//http://localhost:8080/restful-webservices/users/id/addresses
@GetMapping(path = "/{id}/addresses",
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} )
public List<AddressesRest> getUserAddresses(@PathVariable String id){
List<AddressesRest> returnValue = new ArrayList<>();
List<AddressDTO> addressesDTO = addressesService.getAddresses(id);
if(addressesDTO != null && !addressesDTO.isEmpty()){
Type listType = new TypeToken<List<AddressesRest>>(){}.getType();
returnValue = new ModelMapper().map(addressesDTO, listType);
}
return returnValue;
}
@GetMapping(path="/{userId}/addresses/{addressId}",
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} )
public AddressesRest getUserAddress(@PathVariable String addressId){
AddressDTO addressesDto = addressService.getAddress(addressId);
ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(addressesDto, AddressesRest.class);
}
@PutMapping(path="/{userId}/addresses/{addressId}",
consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public AddressesRest updateAddress(@PathVariable String id, @RequestBody AddressesRequestModel addressDetails){
AddressesRest returnValue = new AddressesRest();
if(addressDetails.getCity().isEmpty()
|| addressDetails.getCountry().isEmpty()
|| addressDetails.getPostalCode().isEmpty()
|| addressDetails.getStreetName().isEmpty()
|| addressDetails.getType().isEmpty()) throw new NullPointerException("The object is null");
AddressDTO addressDto = new AddressDTO();
BeanUtils.copyProperties(addressDetails, addressDto);
AddressDTO updatedAddress = addressService.updateAddress(id, addressDto);
BeanUtils.copyProperties(updatedAddress,returnValue);
return returnValue;
}
}
这是我的repo
如何解决此错误?有什么想法吗?
谢谢
Theo。
答案 0 :(得分:3)
缺少String类型的方法参数的URI模板变量'id'
该消息很清楚。它说您已经定义了一个名为“ id”的路径变量,但是URI中没有任何这样的模板变量。确实:
@PutMapping(path="/{userId}/addresses/{addressId}", // there is no {id} in the path
...)
public AddressesRest updateAddress(@PathVariable String id, // there should be an {id} in the path
...
答案 1 :(得分:2)
您已经声明了两个路径变量,名称分别为userId
和addressId
,但是只有一个方法参数带有@PathVariable
注释,名为id
。您可以更正方法参数:
@PutMapping(path="/{userId}/addresses/{addressId}",
consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public AddressesRest updateAddress(@PathVariable String userId, @PathVariable String addressId, @RequestBody AddressesRequestModel addressDetails){
// ...
}
如果adressIds是唯一的,则userId是多余的,因此您还可以更改URI:
@PutMapping(path="/address/{id}",
consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public AddressesRest updateAddress(@PathVariable String id, @RequestBody AddressesRequestModel addressDetails){
// ...
}
答案 2 :(得分:1)
在updateAddress方法中,您应该传递两个参数的路径变量。
@PutMapping(path="/{userId}/addresses/{addressId}",
consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public AddressesRest updateAddress(@PathVariable String userId, @PathVariable String addressId, @RequestBody AddressesRequestModel addressDetails){
AddressesRest returnValue = new AddressesRest();
if(addressDetails.getCity().isEmpty()
|| addressDetails.getCountry().isEmpty()
|| addressDetails.getPostalCode().isEmpty()
|| addressDetails.getStreetName().isEmpty()
|| addressDetails.getType().isEmpty()) throw new NullPointerException("The object is null");
AddressDTO addressDto = new AddressDTO();
BeanUtils.copyProperties(addressDetails, addressDto);
AddressDTO updatedAddress = addressService.updateAddress(addressId, addressDto);
BeanUtils.copyProperties(updatedAddress,returnValue);
return returnValue;
}