我试图实现一个场景,希望能够将JSON对象数组作为请求体发送到Spring MVC控制器。
但这些建议没有一个奏效。如果我错过了其他的帖子,我向你道歉。
@RequestMapping("/config")
public class ConfigController {
@Autowired
private final Service service;
// This works. I don't know why.
@RequestMapping("/fetch", method=RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public String readConfigProperties() throws Exception {
ImmutableList<Config> configObjects = this.service.readConfiguration();
return configObjects;
}
}
更新:我在这篇文章的前一个版本中使用了@ResponseBody注释。我将帖子改为使用@RequestBody,但没有影响。
@RequestMapping(method=RequestMethod.POST, consumes={"application/json"}, value="/update}
@ResponseStatus(HttpStatus.OK)
public void updateConfig(@RequestBody List<Config> configList) throws Exception {
this.service.updateConfiguration(configList);
}
在本例中,configList是LinkedHashMap对象的列表,因此它会引发ClassCastException。我不知道为什么。
我的标题如下:
Content-Type: application/json; charset=utf-8
java.lang.ClassCastException: java.util.LinkedHashMap incompatible with com.kartik.springmvc.model.Config
com.kartik.springmvc.service.ConfigPropertyService.upsertConfigurationProperties(ConfigPropertyService.java:56)
com.kartik.springmvc.controller.ConfigController .upsertConfigurationProperties(ConfigController .java:86)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:88)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
java.lang.reflect.Method.invoke(Method.java:613)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
<context:annotation-config />
<context:component-scan base-package="com.kartik.springmvc.controller" />
<bean class="com.kartik.springmvc.controller.AppConfigPropertiesConverter" id="appConfigPropertiesConverter"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="appConfigPropertiesConverter" />
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
<mvc:annotation-driven/>
下面给出了我的转换器实现。更新:未调用此类。
public class AppConfigPropertiesConverter extends AbstractHttpMessageConverter<Object> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Gson gson = new Gson();
/**
* Construct a new {@code GsonHttpMessageConverter}.
*/
public AppConfigPropertiesConverter() {
super(new MediaType("application", "json", DEFAULT_CHARSET), new MediaType(
"application", "*+json", DEFAULT_CHARSET));
}
/** Supports only {@link Config} instances. */
@Override
protected boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
return true;
}
/**
* Converts to a list of {@Config}
*/
@Override
protected Object readInternal(
Class<?> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
TypeToken<?> token = TypeToken.get(clazz);
System.out.println("#################################################################3");
Reader jsonReader =
new InputStreamReader(inputMessage.getBody(), DEFAULT_CHARSET.displayName());
System.out.println("####################################################################");
try {
return this.gson.fromJson(jsonReader, token.getType());
} catch (JsonParseException ex) {
throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);
}
}
/**
* Write the json reprsentation to {@link OutputStream}.
*
* @param config object to be serialized
* @param output http output message
*/
@Override
protected void writeInternal(
Object config, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
outputMessage.getBody().write(
this.gson.toJson(config).getBytes(DEFAULT_CHARSET.displayName()));
}
}
更新:增加了服务层
public class ConfigPropertyService implements IConfigPropertyService {
private final Log LOG = LogFactory.getLog(ConfigPropertyService.class);
private final IConfigPropertyDao<Config> configPropertyDao;
/**
* Returns the instance of Dao.
*/
@Override
public IConfigPropertyDao<Config> getConfigPropertyDao() {
return this.configPropertyDao;
}
/**
* Initializes the data access tier.
*/
public ConfigPropertyService(IConfigPropertyDao<Config> configPropertyDao) {
this.configPropertyDao = Objects.requireNonNull(configPropertyDao);
}
/**
* {@inheritDoc}
* @throws ConfigServiceException if the resources can't be cleaned up successfully
*/
@Override
public void upsertConfigurationProperties(
ImmutableList<Config> configModels) {
for (Config config: configModels) {
// This for loop throws an exception.
}
// Step # 2: Updating the properties.
this.configPropertyDao.upsertProperties(configModels);
}
/**
* {@inheritDoc}
*/
@Override
public ImmutableList<ConfigModel> readConfigProperties() {
return this.configPropertyDao.readProperties();
}
}
我的请求体给出如下。它是一个带有内容类型的字符串体:application/json;charset=utf-8
[{"propertyName":"anchorIndexingFilter.deduplicate","propertyValue":"false","propertyDescription":"With this enabled the indexer will case-insensitive deduplicate hanchors\n before indexing. This prevents possible hundreds or thousands of identical anchors for\n a given page to be indexed but will affect the search scoring (i.e. tf=1.0f).\n ","editable":true}]
问题是方法签名将LinkedHashMap作为参数传递,但在方法中接收的是配置对象列表,这会导致类转换异常
public void updateConfig(@RequestBody List<Config> configList)
将上面的内容改为类似这样的内容不完全是
public void updateConfig(@RequestBody LinkedHashMap<K,V> configList)
我正在尝试在更改选项后将我的Thymeleaf超文本标记语言中已经提供的List传回控制器。我尝试过隐藏输入,但不幸的是,它还不起作用。 我的表单如下所示(控制器已经提供了“电影”列表) 我的控制器看起来像这样: 期待有人能帮助我!
我正在尝试将一个对象(或只是ID)传递给我的控制器,我从下拉列表中选择它。有2个类:产品和类别(产品包含一个外键,这是类别的ID)这是我如何将其加载到: 如您所见,我正在将对象类别传递到我的. jsp中。在那里我显示了用户可以选择的所有类别。 该值应该传递给我的控制器,但我不知道如何传递它。
问题内容: 我正在将一个对象传递给我的控制器,如下所示: 我的控制器将其视为它正在寻找的对象: 我的问题是我只想再传递一个字符串。我知道我可以制作特定于视图的模型,但我想知道是否可以执行以下操作: 我没有运气就尝试了以下方法: 但是复杂对象只是作为null来的。有没有办法我也可以传递对象和字符串? 问题答案: 尝试将字符串项添加到已有的JSON中。不要对其进行字符串化,否则它将发送一个大字符串,您
问题内容: 我有以下任意JSON对象(字段名称可能会更改)。 -- 我知道我可以像定义具有相同字段名的JSON对象那样定义类,但是我希望控制器接受具有不同字段名的任意JSON对象。 问题答案: 如果您想将自定义JSON对象传递给MVC操作,则可以使用此解决方案,它的工作原理很吸引人。 该解决方案的真正好处是,您不需要为每个参数组合定义一个新类,并且除此之外,您可以轻松地将对象转换为其原始类型。 更
如果对象为NULL,则无法传递对象项目。如何将对象从HTML传递给spring控制器?
问题内容: 我正在使用.Net 4,MVC 3和jQuery v1.5做一些工作 我有一个JSON对象,它可以根据调用它的页面而改变。我想将对象传递给控制器。 我了解如果我创建一个自定义模型,例如 并在我的控制器中使用它,例如 并使用jQuery的.ajax方法传递对象,如下所示: 这工作正常,我的JSON对象已映射到我的C#对象。我想做的是通过一个可能更改的JSON对象。当它更改时,我不需要