Lam*_*bda 5 spring spring-mvc spring-data-jpa spring-boot
我有一个名为person的数据库:
id | first_name | last_name | date_of_birth
----|------------|-----------|---------------
1 | Tin | Tin | 2000-10-10
Run Code Online (Sandbox Code Playgroud)
有一个名为JPA的实体Person
映射到此表:
@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
}
Run Code Online (Sandbox Code Playgroud)
该实体还使用JAXB注释进行注释,以允许将HTTP请求中的XML有效负载映射到实体的实例.
我想实现一个端点,用于检索和更新具有给定的实体id
.
根据对类似问题的回答,我需要做的就是实现如下的处理程序方法:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这不能按预期工作,因为可以通过以下失败的测试用例进行验证:
@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<Object> request = new HttpEntity<>("<person first-name=\"Tin Tin\" last-name=\"Herge\" dob=\"1907-05-22\"></person>", headers);
final ResponseEntity<Person> response = restTemplate.exchange("/persons/1", PUT, request, Person.class, "1");
assertThat(response.getStatusCode(), equalTo(OK));
final Person body = response.getBody();
assertThat(body.getFirstName(), equalTo("Tin Tin")); // Fails
assertThat(body.getLastName(), equalTo("Herge"));
assertThat(body.getDateOfBirth(), equalTo("1907-05-22"));
}
}
Run Code Online (Sandbox Code Playgroud)
第一个断言失败了:
java.lang.AssertionError:
Expected: "Tin Tin"
but: was "Tin"
Expected :Tin Tin
Actual :Tin
Run Code Online (Sandbox Code Playgroud)
换一种说法:
200
)id=1
有什么想法我在这里缺少什么?
这里提供的解决方案不起作用.
id=1
Jaxb2RootElementHttpMessageConverter
或使用XML有效内容填充加载的人员实体的属性MappingJackson2XmlHttpMessageConverter
person
参数传递给控制器的动作处理程序id=1
已加载Person实例这个 '@PutMapping(value = "/{person}")' 带来了一些魔力,因为在你的例子中 {person} 只是 '1',但它恰好从数据库加载它并放入控制器中的 ModelAttribute 。无论您在测试中进行什么更改(甚至可以为空),spring都会从数据库加载人员(有效地忽略您的输入),您可以在控制器的第一行停止调试器来验证它。
您可以这样使用它:
@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);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3122 次 |
最近记录: |