Tenho um projeto java com epenas dois arquivos, uma interface e uma classe.
Essa interface extende a interface br.com.caelum.vraptor.View para tratar alguns casos específicos na serialização de objetos JSON.
ExtJSJson.java
import br.com.caelum.vraptor.View;
public interface ExtJSJson extends View {
public ExtJSJsonImpl from(Object object);
public ExtJSJsonImpl success();
public ExtJSJsonImpl success(boolean success);
public ExtJSJsonImpl selected(Object value);
public ExtJSJsonImpl exclude(String... names);
public ExtJSJsonImpl include(String... fields);
public ExtJSJsonImpl upload(String fileName);
public ExtJSJsonImpl serialize();
}
E a implantação dela na classe ExtJSJsonImpl.java
@Component
public class ExtJSJsonImpl implements ExtJSJson {
private final Multimap<Class<?>, String> excludes = LinkedListMultimap.create();
private final XStream xstream;
private final HttpServletResponse response;
private final String SUCCESS = "{\"success\": ";
private final String SELECTED = ",\n \"selected\": @value }";
private Set<Class<?>> elementTypes;
private Class<?> rootClass;
private Object object;
private String json;
private boolean convertToJson = true;
private boolean includeSuccess = false;
private boolean successValue = true;
private boolean includeSelected = false;
private Object selectedValue;
public ExtJSJsonImpl(HttpServletResponse response) {
this.xstream = new XStream(new JsonHierarchicalStreamDriver());
this.response = response;
}
public ExtJSJsonImpl from(Object object) {
response.setContentType("application/json; charset=ISO-8859-1");
this.rootClass = object.getClass();
this.object = object;
return this;
}
public ExtJSJsonImpl success() {
return success(true);
}
public ExtJSJsonImpl success(boolean success) {
includeSuccess = true;
successValue = success;
return this;
}
public ExtJSJsonImpl selected(Object value) {
if(value != null) {
includeSelected = true;
selectedValue = value;
}
return this;
}
public ExtJSJsonImpl exclude(String... names) {
for (String name : names) {
Set<Class<?>> parentTypes = getParentTypesFor(name);
for (Class<?> type : parentTypes) {
xstream.omitField(type, getNameFor(name));
}
}
return this;
}
public ExtJSJsonImpl include(String... fields) {
for (String field : fields) {
try {
Set<Class<?>> parentTypes = getParentTypesFor(field);
String fieldName = getNameFor(field);
for (Class<?> parentType : parentTypes) {
Type genericType = new Mirror().on(parentType).reflect().field(fieldName).getGenericType();
Class<?> fieldType = getActualType(genericType);
if (!excludes.containsKey(fieldType)) {
excludeNonPrimitiveFields(fieldType);
}
excludes.remove(parentType, fieldName);
}
} catch (NullPointerException e) {
throw new IllegalArgumentException("Field path " + field + " doesn't exist");
}
}
return this;
}
public ExtJSJsonImpl upload(String fileName) {
response.setContentType("text/html");
convertToJson = false;
fileName = fileName != null ? fileName : "undefined";
json = "{success:" + successValue + ", file:\"" + fileName + "\"}";
return this;
}
public ExtJSJsonImpl serialize() {
if(convertToJson)
this.json = objectToJSON();
if(includeSelected)
includeSelected();
if(includeSuccess)
includeSuccess();
try {
response.getWriter().write(json);
} catch (IOException e) {
e.printStackTrace();
}
return this;
}
private void excludeNonPrimitiveFields(Class<?> type) {
for (Field field : new Mirror().on(type).reflectAll().fields()) {
if (!isPrimitive(field.getType())) {
excludes.put(type, field.getName());
}
}
}
private String objectToJSON() {
xstream.setMode(XStream.NO_REFERENCES);
xstream.alias("data", object.getClass());
for(Class clazz : object.getClass().getInterfaces()) {
xstream.alias("data", clazz);
}
String json = xstream.toXML(object).trim();
if(json.endsWith("}}")) {
json = json.substring(0, json.length() - 2) + " }\n}";
}
return json;
}
private String getNameFor(String name) {
String[] path = name.split("\\.");
return path[path.length-1];
}
private Set<Class<?>> getParentTypesFor(String name) {
if (elementTypes == null) {
Class<?> type = rootClass;
return Collections.<Class<?>>singleton(getParentType(name, type));
} else {
Set<Class<?>> result = new HashSet<Class<?>>();
for (Class<?> type : elementTypes) {
result.add(getParentType(name, type));
}
return result;
}
}
private Class<?> getParentType(String name, Class<?> type) {
String[] path = name.split("\\.");
for (int i = 0; i < path.length - 1; i++) {
type = getActualType(new Mirror().on(type).reflect().field(path[i]).getGenericType());
}
return type;
}
private Class<?> getActualType(Type genericType) {
if (genericType instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType) genericType;
if (isCollection(type)) {
return (Class<?>) type.getActualTypeArguments()[0];
}
}
return (Class<?>) genericType;
}
private boolean isCollection(Type type) {
if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
return Collection.class.isAssignableFrom((Class<?>) ptype.getRawType())
|| Map.class.isAssignableFrom((Class<?>) ptype.getRawType());
}
return Collection.class.isAssignableFrom((Class<?>) type);
}
private void includeSuccess() {
if(json != null && json.length() > 0 && json.startsWith("{") && json.endsWith("}")) {
this.json = SUCCESS + successValue + ", \n " + this.json.substring(1);
}
}
private void includeSelected() {
if(json != null && json.length() > 0 && json.startsWith("{") && json.endsWith("}")) {
String v = null;
if(isNumeric(selectedValue.getClass())) {
v = selectedValue.toString();
} else {
v = "\"" + selectedValue.toString() + "\"";
}
this.json = this.json.substring(0, json.length() - 1) + SELECTED.replace("@value", v);
}
}
private boolean isPrimitive(Class<?> type) {
return type.isPrimitive()
|| type.isEnum()
|| Number.class.isAssignableFrom(type)
|| type.equals(String.class)
|| Date.class.isAssignableFrom(type)
|| Calendar.class.isAssignableFrom(type)
|| Boolean.class.equals(type)
|| Character.class.equals(type);
}
private boolean isNumeric(Class clazz) {
return Integer.class.equals(clazz)
|| Double.class.equals(clazz)
|| Long.class.equals(clazz)
|| Number.class.equals(clazz);
}
}
Quando eu deixo as classes diretamente no projeto WEB, o sistema roda tranquilamente.
Contudo, se eu compilo um JAR com as duas classes e adiciono o mesmo na lib do projeto, quando aciono esse classe recebo o seguinte erro:
24/06/2010 16:25:41 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet default threw exception
br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.k2studio.vraptor.interceptor.LoginInterceptor.intercept(LoginInterceptor.java:37)
at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [br.com.k2studio.vraptor.extjs.ExtJSJson] is defined: no bean for this type registered
at br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext.getBean(VRaptorApplicationContext.java:255)
at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:59)
at br.com.caelum.vraptor.core.DefaultResult.use(DefaultResult.java:48)
at br.com.k2studio.vraptor.controller.ExtjsController.combobox(ExtjsController.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
... 40 more
24/06/2010 16:25:41 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet default threw exception
br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.k2studio.vraptor.interceptor.LoginInterceptor.intercept(LoginInterceptor.java:37)
at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [br.com.k2studio.vraptor.extjs.ExtJSJson] is defined: no bean for this type registered
at br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext.getBean(VRaptorApplicationContext.java:255)
at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:59)
at br.com.caelum.vraptor.core.DefaultResult.use(DefaultResult.java:48)
at br.com.k2studio.vraptor.controller.ExtjsController.grid(ExtjsController.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
... 40 more
Alguém sabe como posso resolver isso?
[]´s
Daniel