我使用 REST 调用创建了一个 WebService。
GET 和 DELETE 调用都可以。现在,当我发布资源时,Java 方法总是被调用两次!当我 PUT 一个资源时,POST 方法会在 PUT 之后自动调用。
我不知道如何解决此问题以下是代码文档:
首先,Spring DAO XML:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.asefa.club.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</bean>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/asefa-core_club" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<context:annotation-config />
<bean id="clubDao" class="com.asefa.club.dao._impl.ClubDao" />
实体 Java 类
@Entity
@NamedQueries({
@NamedQuery(name = "Club.getByName", query = "select c from Club c where c.nameShort = :name")})
public class Club implements Serializable {
@Id
@GeneratedValue
private long id;
private String name;
private String nameShort;
private String nameInitials;
private Date dateCreation;
@Lob
private byte[] picture;
@OneToOne
@JsonManagedReference
private Stadium stadium;
@OneToOne
@JsonManagedReference
private President president;
@OneToMany(mappedBy = "club", cascade = CascadeType.ALL)
@JsonManagedReference
private List<Team> teams;
@OneToMany(mappedBy = "club", cascade = CascadeType.ALL)
@JsonManagedReference
private List<Player> players;
@OneToMany(mappedBy = "club", cascade = CascadeType.ALL)
@JsonManagedReference
private List<Staff> staffs;
@OneToMany(mappedBy = "club", cascade = CascadeType.ALL)
@JsonManagedReference
private List<Trainer> trainers;
// setters and getters
}
DAO Java 类
public class ClubDao implements IClubDao {
@PersistenceContext
EntityManager entityManager;
public void createClub(Club club) {
entityManager.persist(club);
}
public void updateClub(Club club) {
entityManager.merge(club);
}
public void deleteClub(Club club) {
Club c = getClub(club.getId());
entityManager.remove(c);
}
public Club getClub(Long id) {
return entityManager.find(Club.class, id);
}
@SuppressWarnings("unchecked")
public Club getClubByName(String name) {
List<Club> clubs = entityManager.createNamedQuery("Club.getByName")
.setParameter("name", name).getResultList();
Club club = null;
if (!clubs.isEmpty()) {
club = clubs.get(0);
}
return club;
}
业务 Java 类
@Transactional
public class ClubBo implements IClubBo {
private IClubDao clubDao;
public IClubDao getClubDao() {
return clubDao;
}
@Autowired
public void setClubDao(IClubDao clubDao) {
this.clubDao = clubDao;
}
public void postClub(Club club) throws ClubException {
Club existingClub = getClubByName(club.getName());
if (existingClub == null) {
clubDao.createClub(club);
} else {
throw new ClubException("Club already exist", 1011);
}
}
public void putClub(Club club) throws ClubException {
Club existingClub = getClub(club.getId());
if (existingClub != null) {
clubDao.updateClub(club);
} else {
throw new ClubException("Club does not exist", 1012);
}
}
public void deleteClub(Club club) throws ClubException {
Club existingClub = getClub(club.getId());
if (existingClub != null) {
clubDao.deleteClub(club);
} else {
throw new ClubException("Club does not exist", 1012);
}
}
public Club getClub(Long id) {
return clubDao.getClub(id);
}
public Club getClubByName(String name) {
return clubDao.getClubByName(name);
}
}
最后是使用 CXF 的 REST 服务(仅使用的方法)
@GET
@Path("/club/{clubName}")
@Produces(MediaType.APPLICATION_JSON)
public Club getClub(@PathParam("clubName") String clubName) {
return coreClubApplication.getClub(clubName);
}
@POST
@Path("/club/{clubName}")
@Consumes(MediaType.APPLICATION_JSON)
public void createClub(@PathParam("clubName") String clubName,
ClubJsonData clubJsonData) throws ClubException {
Club club = new Club();
club.setName(clubJsonData.getName());
club.setNameShort(clubName);
club.setNameInitials(clubJsonData.getNameInitials());
club.setDateCreation(clubJsonData.getDateCreation());
coreClubApplication.createClub(club);
}
@PUT
@Path("/club/{clubName}")
@Consumes(MediaType.APPLICATION_JSON)
public void updateClub(@PathParam("clubName") String clubName,
ClubJsonData clubJsonData) throws ClubException {
Club club = getClub(clubName);
club.setName(clubJsonData.getName());
club.setNameInitials(clubJsonData.getNameInitials());
club.setDateCreation(clubJsonData.getDateCreation());
coreClubApplication.updateClub(club);
}
@DELETE
@Path("/club/{clubName}")
public void deleteClub(@PathParam("clubName") String clubName)
throws ClubException {
Club club = getClub(clubName);
coreClubApplication.deleteClub(club);
}
因此,当使用 SoapUI 测试 REST URI 时,我想发布一个资源(新俱乐部)并且方法 createClub 被调用了两次!当我想修改它时,在 PUT 之后自动调用 POST 方法。
任何想法 ?
谢谢 :)