MessageBodyWriter not found for media type=applica

Jersey2+Spring4+Hibernate4java

在Resource類中獲取某一個id的User對象以xml方式顯示在頁面上時,提示以下異常:spring

Caused by: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/xml, type=class entity.User_$$_jvst87_0, genericType=class entity.User.
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:247)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
	at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
	at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
	... 49 more

實體類User以下:sql

package entity;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import config.DateAdapter;



@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@XmlRootElement
@XmlType(name = "user", propOrder = {
	    "id",
	    "name",
	    "salary",
	    "birthday"}
	)
public class User {
	private long id; 
	private String name;
	private Double salary;
	private Date birthday;
	
	
	public User() {
	}
	public User(long id, String name, Double salary, String birthday) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
		try {
			this.birthday = new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	public User(String name, Double salary, String birthday) {
		super();
		this.name = name;
		this.salary = salary;
		try {
			this.birthday = new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	
	
	@XmlJavaTypeAdapter(DateAdapter.class)
	public Date getBirthday() {
		return birthday;
	}
	
	
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	
	@Id
	@GeneratedValue
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	
	
	@Override
	public String toString() {
		String birthdayS = (new SimpleDateFormat("yyyy-MM-dd")).format(birthday);
		return "User : id="+id+", Name="+name+", Salary="+salary+", Birthday="+birthdayS;
	}
}

Reource類以下:app

package resource;
 
import java.util.List;

import javax.annotation.Resource;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.MessageBodyWriter;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import entity.User;
import service.UserService;;
 
@Singleton
@Path("user")
@Component     //@Repository/@Service/@Controller
public class UserResource {
 
	@Context 
	UriInfo uri;
	
	@Context 
	HttpHeaders header;
	
    private UserService userService;  //Service which will do all data retrieval/manipulation work
 
     
    public UserService getUserService() {
		return userService;
	}

    @Resource
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

    
    
    @GET
    @Path("/list")
//    @Produces(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_XML)
    public List<User> listAllUsers() {
        return userService.getUsers();
    }
 
 
    //-------------------Retrieve Single User--------------------------------------------------------
     
    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_XML)
//    @Produces({MediaType.APPLICATION_JSON})
    public User getUser(@PathParam("id") long id) {
        System.out.println("Fetching User with id " + id);
        User user = userService.getUserById(id);
        
//        User user = new User("n",5000.0,"2015-15-12");
        System.out.println(user);
        return user;
    }
 
     
   
}

UserDaoImpl.java:ide

package dao;

import java.util.List;


import javax.annotation.Resource;

import org.springframework.orm.hibernate4.HibernateTemplate;

import entity.User;

public class UserDaoImpl implements UserDao {
	private HibernateTemplate hibernateTemplate;
	
	
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}
	
	@Resource
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
	
	
	/* (non-Javadoc)
	 * @see dao.UserDao#checkUserExistsByUname(java.lang.String)
	 */
	@Override
	public boolean checkUserExistsByUname(String name){
		//String sql = "select count(*) from User where uname = '"+uname+"'";
		String sql = "from User where name = '"+name+"'";
		List list = (List) hibernateTemplate.find(sql);
		if(list!=null&&list.size()>0){
			return true;
		}
		
	    return false;
	}
	
	/* (non-Javadoc)
	 * @see dao.UserDao#save(entiey.User)
	 */
	@Override
	public void save(User user){
		hibernateTemplate.save(user);
	}

	@Override
	public List<User> getUsers() {
		return (List<User>) hibernateTemplate.find("from User");
	}

	@Override
	public User getUserById(long id) {
		return hibernateTemplate.load(User.class, id);
		
	}


	@Override
	public void updateUser(User user) {
		hibernateTemplate.update(user);
		
	}

	@Override
	public void deleteUserById(long id) {
//		hibernateTemplate.delete(getUserById(id));
		hibernateTemplate.bulkUpdate("delete User where id=?",id);
		
	}

	@Override
	public void deleteAllUsers() {
		hibernateTemplate.bulkUpdate("delete User");
		
	}
}

後來根據異常足跡debug了下:WriterInterceptorExecutor-->MessageBodyFactory,到這個類時,裏面有個方法以下:
this

這裏的provider.isWriteable()返回的是false,由於type不是User類型,而是User的代理類(User_$$_rst101_0),User類因有@XmlRootElement,因此可由jersey自動轉成xml類型,但User的代理類,jersey沒有對應的MessageBodyWriter將其寫出,故報異常。至此,緣由已經清晰,解決方法就是讓拿到的User對象是真正的User對象,而不是代理。因爲在dao層獲取某一個id的user對象是經過load()方法獲取的。hibernate

hibernateTemplate.load(User.class, id)

load()拿到的是一個代理對象。這時只需改爲get()便可。debug

hibernateTemplate.get(User.class, id)

小數據量、簡單業務狀況下,不要使用load(),使用get()。代理

相關文章
相關標籤/搜索