Обновление адреса пользователя - весенний отдых

Поэтому я создал следующий API для отдыха, используя Spring 5.

http://localhost:8080/restful-webservices/users/DtvQLbP5uUXaJr4y5n2yxch3BODQCd

{
"userId": "DtvQLbP5uUXaJr4y5n2yxch3BODQCd",
"firstName": "T",
"lastName": "T",
"email": "[email protected]",
"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"
}

Вот мой класс АдресСервисИмпл

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

Это мой репо

Как можно исправить эту ошибку? Есть идеи?

Спасибо,

Тео.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
182
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Missing URI template variable 'id' for method parameter of type String

Сообщение ясно. В нем говорится, что вы определили переменную пути с именем «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
                                       ...

Вы объявили две переменные пути с именами 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){
// ...
}

Если идентификаторы адресов уникальны, тогда идентификатор пользователя является избыточным, поэтому вы также можете изменить 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){
// ...
}

В вашем методе 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;
    }

Другие вопросы по теме