简体   繁体   中英

Java based Configuration for Spring Restful Web Services with JAXB

I am facing an issue while creating Restful Web Services in Spring MVC. I am using Java Based Configuration instead of XML Based Configuration. When i try to access the service i get

Error 500--Internal Server Error
java.lang.NoSuchMethodError: supports
at org.springframework.http.converter.xml.MarshallingHttpMessageConverter.supports(MarshallingHttpMessageConverter.java:109)
at org.springframework.http.converter.AbstractHttpMessageConverter.canWrite(AbstractHttpMessageConverter.java:125)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:136)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:80)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:94)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:69)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:604)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:565)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:779)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:821)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:176)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3498)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Unknown Source)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)

Below is my User Domain Class:

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "userType")
@XmlRootElement(name = "user")
public class User {
private long id;
private String name;
private Date registrationDate;

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Date getRegistrationDate() {
    return registrationDate;
}

public void setRegistrationDate(Date registrationDate) {
    this.registrationDate = registrationDate;
}

@Override
public String toString() {
    return "The Id is"+getId()+"The name is"+getName()+"The registration date"+getRegistrationDate();
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (!(obj instanceof User)) {
        return false;
    }
    User other = (User) obj;
    //EqualsBuilder equalsBuilder = new EqualsBuilder();
    //equalsBuilder.append(getId(), other.getId());
    //return equalsBuilder.isEquals();
    return true;
}

My Userlist Class is as follows:

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "userListType")
@XmlRootElement(name = "userList",namespace = "com.commercial.mpmapprovals.domain")

public class UserList {
private List<User> users = new ArrayList<User>();

public UserList() {}

public UserList(List<User> users) {
    this.users = users;
}

@XmlElement(name = "user")
public List<User> getUsers() {
    return users;
}

public void setUsers(List<User> users) {
    this.users = users;
   }
}

My User Service implementation class for CRUD is below:

@Service
public class UserServiceImpl implements UserService{
private final AtomicLong USER_ID_SEQ = new AtomicLong();
private final ConcurrentMap<Long, User> usersMap = new ConcurrentHashMap<Long, User>();

@Override
public User create(User user) {
    user.setId(USER_ID_SEQ.incrementAndGet());
    usersMap.put(user.getId(), user);
    return user;
}

@Override
public User read(long userId) {
    return usersMap.get(userId);
}

@Override
public User update(User user) {
    User updatedUser = usersMap.replace(user.getId(), user);
   // Validate.isTrue(updatedUser != null, "Unable to find user with id: " + user.getId());
    return updatedUser;
}


@Override
public User delete(long userId) {
    User removedUser = usersMap.remove(userId);
   // Validate.isTrue(removedUser != null, "Unable to find user with id: " + userId);
    return removedUser;
}

@Override
public Collection<User> list() {
    User user1=new User();
    user1.setId(1L);
    user1.setName("User1");
    user1.setRegistrationDate(new Date());
    usersMap.put(user1.getId(), user1);
    User user2=new User();
    user2.setId(2L);
    user2.setName("User2");
    user2.setRegistrationDate(new Date());
    usersMap.put(user2.getId(), user2);
    return usersMap.values();
    }
}

My User Controller is as shown below:

@Controller
@RequestMapping(value = "/users")
public class UserController {
private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

@Autowired
private UserService userService;

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public User create(@RequestBody User user) {
    LOGGER.info("Creating new user {}", user);
    return userService.create(user);
}

@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
@ResponseBody
public User read(@PathVariable(value = "userId") long userId) {
    LOGGER.info("Reading user with id {}", userId);
    User user = userService.read(userId);
   // Validate.isTrue(user != null, "Unable to find user with id: " + userId);
    return user;
}

@RequestMapping(value = "/{userId}", method = RequestMethod.PUT)
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void update(@PathVariable(value = "userId") long userId, @RequestBody User user) {
    LOGGER.info("Updating user with id {} with {}", userId, user);
   // Validate.isTrue(userId == user.getId(), "userId doesn't match URL userId: " + user.getId());
    userService.update(user);
}

@RequestMapping(value = "/{userId}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void delete(@PathVariable(value = "userId") long userId) {
    LOGGER.info("Deleting user with id {}", userId);
    userService.delete(userId);
}

@RequestMapping(value = "/users", method = RequestMethod.GET,produces = "application/xml")
@ResponseBody
public UserList list() {
    System.out.println("Inside the List function");
    LOGGER.info("Listing users");
    return new UserList(new ArrayList<User>(userService.list()));
}

@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public String handleClientErrors(Exception ex) {
    LOGGER.error(ex.getMessage(), ex);
    return ex.getMessage();
}

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public String handleServerErrors(Exception ex) {
    LOGGER.error(ex.getMessage(), ex);
    return ex.getMessage();
    }
}

My POM file has the following dependencies

 <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-oxm-tiger</artifactId>
        <version>1.0-m2</version>
 </dependency>
 <dependency>
            <groupId>org.springframework.ws</groupId>
            <artifactId>spring-ws</artifactId>
            <version>1.5.0</version>
 </dependency>
             <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
  </dependency>

All the other dependincies are also added in the POM File

My Java Based Configuration Class is as shown below:

public class WebConfiguration extends WebMvcConfigurerAdapter {
@Bean
public Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setClassesToBeBound(User.class);
    return marshaller;
}  

@Bean
public Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setClassesToBeBound(User.class);
    return marshaller;
}

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    super.configureMessageConverters(converters);

    HibernateModule hibernateModule = new HibernateModule();
    hibernateModule.configure(HibernateModule.Feature.FORCE_LAZY_LOADING, false);

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    objectMapper.registerModule(hibernateModule);

    MappingJacksonHttpMessageConverter jacksonHttpMessageConverter = new MappingJacksonHttpMessageConverter();
    jacksonHttpMessageConverter.setObjectMapper(objectMapper);

    converters.add(jacksonHttpMessageConverter);

   MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(this.marshaller());
    converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XML));
    converters.add(converter);
}

I have spent a lot of time on this.I am sorry about the very long question. :-) Could some please help me out? Thank you very much.

All of your defined dependencies contain the Unmarshaller interface that is causing this exception. Your problem is that some of these libraries define the supports method to be single argument, and some of the use var args.

You may well find that if you are using Spring 3.xx then you do not need the old tiger jars. Removing them might fix your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM