SpringMvc配置后,只能返回ModelAndView类型

skyjian10 2018-12-18 08:32:28
使用SpringMvc时,在配置文件配置了
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
在@Controller中只能使用ModelAndView类型的方法,不能使用String、Object、Map<String, Object>等作为方法的参数类型。
在return时会出现如下错误:
java.lang.NoSuchMethodError: org.springframework.core.MethodParameter.getContainingClass()Ljava/lang
/Class;
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.support
sReturnType(RequestResponseBodyMethodProcessor.java:83)

at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.getReturnValueHa
ndler(HandlerMethodReturnValueHandlerComposite.java:83)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValu
e(HandlerMethodReturnValueHandlerComposite.java:69)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHan
dle(ServletInvocableHandlerMethod.java:122)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleM
ethod(RequestMappingHandlerAdapter.java:749)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInterna
l(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMe
thodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290
)
............

下面贴上相关代码
springmvc.xml:

<mvc:annotation-driven/>
<mvc:default-servlet-handler/>

<!-- 配置自动扫描的包 spring注解 -->
<context:component-scan base-package="*"></context:component-scan>
<context:component-scan base-package="com.json" />

<!-- 配置视图解析器 如何把handler方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>

controller:正确实例

@Controller
@RequestMapping(value="/system")
public class SysController {

@RequestMapping("/error")
public ModelAndView hello(HttpServletRequest request){
String msg = request.getParameter("msg");
ModelAndView av = new ModelAndView();
av.addObject("msg",msg);
av.setViewName("/sys/error");
return av;
}

方法修饰为ModelAndView 则return正常 不会报错

controller:错误实例

@Controller
@RequestMapping(value="shiro")
public class TestShiroController {

@RequestMapping(value="/testShiro",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public Map<String, Object> testShiro(User user){
Map<String, Object> map = new HashMap<String, Object>();
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),
user.getPassword());
try {
subject.login(token);
} catch (Exception e) {
map.put("msg", e.getMessage());
return map;
}
map.put("msg", "登录成功");
return map;
}

方法修饰为Map,return报错,错误信息如上.同样,参数类型为String、Object,会出现和Map同样的错误.

如果将SpringMvc的配置文件中
springmvc.xml:

<!-- <mvc:annotation-driven/> -->
<!-- <mvc:default-servlet-handler/> -->


<!-- 配置自动扫描的包 spring注解 -->
<context:component-scan base-package="*"></context:component-scan>
<context:component-scan base-package="com.json" />

<!-- 配置视图解析器 如何把handler方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>

<mvc:annotation-driven/>处的两行注释掉,则String、Object修饰的方法都可以正常return

百度了上面查了,说是jar包冲突,删除冲突的jar包试过了,不生效.
不知道有没有大佬出现过我这种情况,在线等......

...全文
334 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
maradona1984 2018-12-21
  • 打赏
  • 举报
回复
引用 4 楼 skyjian10 的回复:
[quote=引用 3 楼 maradona1984 的回复:]
不好意思,没仔细看你的异常信息,你这个大概率是spring相关的jar版本冲突了
可以先检查下spring-core和spring-webmvc两个包是不是版本一致,或者检查下这两个是否存在多个版本
如果用maven,直接用IDE的依赖检查就可以
如果用eclipse(很抱歉我只会eclipse快捷键),ctrl+shift+t 查看 RequestResponseBodyMethodProcessor和MethodParameter这两个类是否存在多个不同版本的jar中


我用大佬你这个方法查了一下,发现在我的Myeclipse下存在spring-core-3.1.1.RELEASE.jar
我的工程又有一个spring-core-4.0.4.RELEASE.jar,我根据提示的路径删除掉了spring-core-3.1.1.RELEASE.jar包,
然而还是提示同样的错误. T-T[/quote]
你得检查spring-web(这个可能是别的)和spring-core的版本,保证一致,而不是随便删除一个

或者研究下类加载的机制,就会明白为什么会产生这种问题

skyjian10 2018-12-21
  • 打赏
  • 举报
回复
引用 3 楼 maradona1984 的回复:
不好意思,没仔细看你的异常信息,你这个大概率是spring相关的jar版本冲突了
可以先检查下spring-core和spring-webmvc两个包是不是版本一致,或者检查下这两个是否存在多个版本
如果用maven,直接用IDE的依赖检查就可以
如果用eclipse(很抱歉我只会eclipse快捷键),ctrl+shift+t 查看 RequestResponseBodyMethodProcessor和MethodParameter这两个类是否存在多个不同版本的jar中


我用大佬你这个方法查了一下,发现在我的Myeclipse下存在spring-core-3.1.1.RELEASE.jar
我的工程又有一个spring-core-4.0.4.RELEASE.jar,我根据提示的路径删除掉了spring-core-3.1.1.RELEASE.jar包,
然而还是提示同样的错误. T-T
maradona1984 2018-12-20
  • 打赏
  • 举报
回复
不好意思,没仔细看你的异常信息,你这个大概率是spring相关的jar版本冲突了
可以先检查下spring-core和spring-webmvc两个包是不是版本一致,或者检查下这两个是否存在多个版本
如果用maven,直接用IDE的依赖检查就可以
如果用eclipse(很抱歉我只会eclipse快捷键),ctrl+shift+t 查看 RequestResponseBodyMethodProcessor和MethodParameter这两个类是否存在多个不同版本的jar中
skyjian10 2018-12-19
  • 打赏
  • 举报
回复
引用 1 楼 maradona1984 的回复:
如果有依赖Fastjson的话,可以

<mvc:annotation-driven enable-matrix-variables="true">
<mvc:message-converters>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"></bean>
</mvc:message-converters>
</mvc:annotation-driven>


当然我们的最佳实践是继承该类,在序列化对象的地方封装成状态对象,但具体方法还是返回业务对象
就拿你这个例子来讲,map不是在controller封装的,而是在MessageConverter里封装的,登录成功这个提示语还是前端自己根据状态吗写

当然上面我说的你完全可以不用,你也可以用jackson,也可以换成springboot,就不要这么纠结


没太理解大佬你说的意思,但是我换成Fastjson试了一下,依然会出现同样的错误.
现在我感觉我只能ModelAndView
return ModelAndView、
或者用void不添加返回类型,直接向页面输出
@RequestMapping(value="/testShiro",method=RequestMethod.POST)
@ResponseBody
public void testShiro(User user,HttpServletResponse response) throws JsonGenerationException, JsonMappingException, IOException{
Map<String, Object> map = new HashMap<String, Object>();
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),
user.getPassword());
try {
subject.login(token);
} catch (Exception e) {
map.put("msg", e.getMessage());
}
map.put("msg", "登录成功");
response.getWriter().print(JSONObject.parseObject(JSON.toJSONString(map)));
}
这样也是可以的

我这里不是为了实现登录的功能,登录功能用ModelAndView已经实现了,我就是想知道,为什么我不能用String、Object、Map作为方法的修饰类型,想知道我的问题出在哪里--

Fastjson我是这样写的

@RequestMapping(value="/testShiro",method=RequestMethod.POST,
produces = "application/json;charset=utf-8")
@ResponseBody
public Object testShiro(User user) throws JsonGenerationException, JsonMappingException, IOException{
Map<String, Object> map = new HashMap<String, Object>();
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),
user.getPassword());
try {
subject.login(token);
} catch (Exception e) {
map.put("msg", e.getMessage());
return map;
}
map.put("msg", "登录成功");
return JSONObject.parseObject(JSON.toJSONString(map));
}

报错信息和最开始的一模一样
maradona1984 2018-12-19
  • 打赏
  • 举报
回复
如果有依赖Fastjson的话,可以

<mvc:annotation-driven enable-matrix-variables="true">
<mvc:message-converters>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"></bean>
</mvc:message-converters>
</mvc:annotation-driven>


当然我们的最佳实践是继承该类,在序列化对象的地方封装成状态对象,但具体方法还是返回业务对象
就拿你这个例子来讲,map不是在controller封装的,而是在MessageConverter里封装的,登录成功这个提示语还是前端自己根据状态吗写

当然上面我说的你完全可以不用,你也可以用jackson,也可以换成springboot,就不要这么纠结

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧