我有一个名为person的数据库:
id | first_name | last_name | date_of_birth
----|------------|-----------|---------------
1 | Tin | Tin | 2000-10-10
有一个名为Person的JPA实体映射到此表:
@Entity
@XmlRootElement(name = "person")
@XmlAccessorType(NONE)
public class Person {
@Id
@GeneratedValue
private Long id;
@XmlAttribute(name = "id")
private Long externalId;
@XmlAttribute(name = "first-name")
private String firstName;
@XmlAttribute(name = "last-name")
private String lastName;
@XmlAttribute(name = "dob")
private String dateOfBirth;
// setters and getters
}
该实体还使用JAXB注释进行注释,以允许XML有效负载
要映射到实体实例的HTTP请求.
我想实现一个端点来检索和更新具有给定id的实体.
根据this answer to a similar question,
我需要做的就是实现如下的处理程序方法:
@RestController
@RequestMapping(
path = "/persons",consumes = APPLICATION_XML_VALUE,produces = APPLICATION_XML_VALUE
)
public class PersonController {
private final PersonRepository personRepository;
@Autowired
public PersonController(final PersonRepository personRepository) {
this.personRepository = personRepository;
}
@PutMapping(value = "/{person}")
public Person savePerson(@modelattribute Person person) {
return personRepository.save(person);
}
}
但是,这不能按预期工作,因为可以通过以下失败的测试用例进行验证:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class PersonControllerTest {
@Autowired
private TestRestTemplate restTemplate;
private HttpHeaders headers;
@Before
public void before() {
headers = new HttpHeaders();
headers.setContentType(APPLICATION_XML);
}
// Test fails
@Test
@DirtiesContext
public void testSavePerson() {
final HttpEntity
第一个断言失败了:
java.lang.AssertionError:
Expected: "Tin Tin"
but: was "Tin"
Expected :Tin Tin
Actual :Tin
换一种说法:
>不会发生服务器端异常(状态代码为200)
> Spring成功加载了id = 1的Person实例
>但其属性不会更新
有什么想法我在这里缺少什么?
注1
笔记2
更多细节
预期行为:
>加载id = 1的Person实例
>使用Jaxb2RootElementHttpMessageConverter或MappingJackson2XmlHttpMessageConverter使用XML有效内容填充加载的人员实体的属性
>将其作为人员参数传递给控制器的动作处理程序
实际行为:
>加载了id = 1的Person实例
>实例的属性未更新以匹配请求有效内容中的XML
>不会更新传递给控制器的操作处理程序方法的person实例的属性
最佳答案
这个’@PutMapping(value =“/ {person}”)带来了一些魔力,因为在你的情况下{person}只是’1′,但它碰巧从数据库加载它并放到控制器中的ModelAttribute.无论你在测试中改变什么(它甚至可能是空的),spring都会从数据库中加载人(有效地忽略你的输入),你可以在第一行控制器上用调试器停止来验证它.
原文链接:https://www.f2er.com/spring/431364.html您可以这样使用它:
@PutMapping(value = "/{id}")
public Person savePerson(@RequestBody Person person,@PathVariable("id") Long id ) {
Person found = personRepository.findOne(id);
//merge 'found' from database with send person,or just send it with id
//Person merged..
return personRepository.save(merged);
}