开发者

Spring RESTFul webservice using Hibernate and JAXB failing to unmarshall XML

开发者 https://www.devze.com 2023-03-17 19:04 出处:网络
I\'ve set up a test Spring webservice using a single entity for my XML un/marshalling and domain entity.

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>
0

精彩评论

暂无评论...
验证码 换一张
取 消