I've set up a test Spring webservice using a single entity for my XML un/marshalling and domain entity.
I'm using maven with embedded Jetty and an embedded H2 database just to test out the service.
When I run a POST to create a "Registration" I can see the following information in my web console:
Hibernate: insert into Registration (id, email, firstName, language, lastName) values (null, ?, ?, ?, ?)
As you can see, the fields in the Object are null and as such the insert fails.
Apologies for the detail but if anyone is going to be able to answer this I guess you need all the following info:
spring-context.xml
<bean="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="marshallingHttpMessageCo开发者_开发问答nverter"/>
</list>
</property>
</bean>
<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"
p:marshaller-ref="jaxb" p:unmarshaller-ref="jaxb" />
<oxm:jaxb2-marshaller id="jaxb">
<oxm:class-to-be-bound name="com.nosh.project.bean.Registration" />
</oxm:jaxb2-marshaller>
<context:component-scan base-package="com.nosh.project.controller" />
<context:component-scan base-package="com.nosh.project" />
<jdbc:embedded-database id="dataSource" type="H2" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource" p:lobHandler-ref="defaultLobHandler"
p:packagesToScan="com.nosh.project.bean">
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
</value>
</property>
</bean>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven proxy-target-class="true"/>
Registration.java (Entity and XML object)
@XmlRootElement(name="registration")
@Entity
public class Registration implements Serializable{
private static final long serialVersionUID = 1L;
private Long id;
private String firstName;
private String lastName;
private String email;
private String language;
public Registration() {
}
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@XmlElement(name = "firstName", required = true)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@XmlElement(name = "lastName", required = true)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@XmlElement(name = "email", required = true)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@XmlElement(name = "language", required = true)
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
}
Controller
@Controller
@RequestMapping("/registration")
@Transactional()
public class RegistrationController {
private RegistrationDao registrationDao;
@Autowired
public void setRegistrationDao(RegistrationDao registrationDao) {
this.registrationDao = registrationDao;
}
//TODO add inbound object validation to check all required fields are correct.
@RequestMapping(method = RequestMethod.POST)
@Transactional(readOnly = false)
@ResponseStatus(HttpStatus.CREATED)
public @ResponseBody
Registration saveRegistration(Registration registration,
BindingResult result, HttpServletResponse response) throws BindException {
if (result.hasErrors()){
throw new BindException(result);
}
registrationDao.saveRegistration(registration);
response.setHeader("Location", "/Registration/" + registration.getId());
return registration;
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseBody
public Registration getRegistration(@PathVariable("id") Long registrationId) {
return registrationDao.getRegistration(registrationId);
}
}
I have looked at several examples and I can't see what I'm missing here. Is it something to do with the fact that I'm using a single object for my data entity and xml unmarshalling?
Many thanks
Long shot here but you may need define supportedMediaTypes
for your marshallingConverter
and then make sure the client is sending the correct Content-Type
header. Here is what I use...
<bean id="marshallingConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxb" />
<property name="supportedMediaTypes" value="application/xml"/>
<property name="marshaller" ref="jaxb" />
<property name="unmarshaller" ref="jaxb" />
</bean>
精彩评论