Springmvc常见问题

问题一:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController': Failed to introspect bean class [com.blog.controller.UserController] for lookup method metadata: could not find class that it depends on; nested exception is java.lang.NoClassDefFoundError: javax/mail/MessagingExceptionhtml

出现这种问题的缘由是由于,以我我的博客为例,我在注册中用到了这个邮箱工具类,邮箱工具类默认抛出Exception和MessagingException异常,而后我去除了该工具类,但未将异常去掉,而后在项目启动中直接报错。若是是用jsp做为表现层直接到首页或者其余界面直接会报500异常。因此说,咱们在Controller中的方法,有时throws异常要慎用。java

广泛的解决办法:就是MVC模式以jsp做为表现层,控制器-模型-视图,经过这种视图跳转的方式,邮箱注册发送邮件是没有任何问题的。若是用纯HTML或纯jsp,而不是经过视图跳转到jsp。web

正常状况下,视图应该是这样的。spring

@RequestMapping("test")
public String test(){

  return "test";

}

  

经过上述这种方式跳转jsp,而不是直接浏览器输入,例如这样的,localhost:8080/test/test.jsp。固然这样返回也能够,可是不太符合MVC这种方式。express

 

 

 

 

 

 

 

 

 

 

问题二:apache

描述:为何返回重复的url呢?明明写了正确的路径。出现这种状况比较多的是由SpringMVC返回JSON数据与前台进行异步交互。‘json

问题缘由:出现这个的问题的缘由是由于个人url正常应该给前台返回json数据,一般在springmvc中url要给前台返回json,必需要定义一个ResponseBody,而我没有定义这个,因此出现了这个异常。设计模式

 

解决办法:浏览器

加上ResponseBody时,就能正常访问到JSON数据spring-mvc

如图所示:

不过一般针对控制层而言,若是某个类基本返回的是JSON,建议使用RestController

这样一来没必要每个方法上都添加@ResponseBody

重复性添加该注解是一件很麻烦的事情,总而言之能偷懒就偷点懒。

下面贴一下RestController的源代码:

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.stereotype.Controller;

/**
 * A convenience annotation that is itself annotated with
 * {@link Controller @Controller} and {@link ResponseBody @ResponseBody}.
 * <p>
 * Types that carry this annotation are treated as controllers where
 * {@link RequestMapping @RequestMapping} methods assume
 * {@link ResponseBody @ResponseBody} semantics by default.
 *
 * <p><b>NOTE:</b> {@code @RestController} is processed if an appropriate
 * {@code HandlerMapping}-{@code HandlerAdapter} pair is configured such as the
 * {@code RequestMappingHandlerMapping}-{@code RequestMappingHandlerAdapter}
 * pair which are the default in the MVC Java config and the MVC namespace.
 * In particular {@code @RestController} is not supported with the
 * {@code DefaultAnnotationHandlerMapping}-{@code AnnotationMethodHandlerAdapter}
 * pair both of which are also deprecated.
 *
 * @author Rossen Stoyanchev
 * @author Sam Brannen
 * @since 4.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     * @since 4.0.1
     */
    String value() default "";

}

 

 

一般状况只要在类上面加上诸如RequstMapping或者其余注解,通常都是全局的。

就如RestController源码同样,看它的注解就能够明白它同时具备Controller和ResponseBody两个特性。

关于经常使用注解这里贴个图,便于回顾:

@Documented的做用:将此注解包含在 javadoc 中 ,它表明着此注解会被javadoc工具提取成文档

 

 

这里在顺便贴下Controller的源码:

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Indicates that an annotated class is a "Controller" (e.g. a web controller).
 *
 * <p>This annotation serves as a specialization of {@link Component @Component},
 * allowing for implementation classes to be autodetected through classpath scanning.
 * It is typically used in combination with annotated handler methods based on the
 * {@link org.springframework.web.bind.annotation.RequestMapping} annotation.
 *
 * @author Arjen Poutsma
 * @author Juergen Hoeller
 * @since 2.5
 * @see Component
 * @see org.springframework.web.bind.annotation.RequestMapping
 * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    String value() default "";

}

 

关于这段源码,简单的说其实关键就是上面的注解。

为何SpringMVC可以经过@Controller+@RequestMapping获得正确的URL

首先不说@RequestMapping,针对如上源码,之因此能够扫描到这个Conroller,关键就在@Component这个注解上。

这个注解能够理解为Struts2的action,对于struts2而言,每一个action是一个实例,所以struts2是多例的。多例意味着,每个对应的action,必需要在配置文件中配置,所以咱们能够看到随着项目的扩大,struts2对应的action相关的xml文件会极速增长的。

而SpringMVC是单例,全局共享一个实例,所以经过@Component直接实例为Spring容器。

简单的说,在咱们初学spring时,要想将对象交给Spring进行管理,一般要配置以下的bean:

以下bean的做用主要是扫描com.eluzhu.rms.mapper的文件下的数据访问层的代码,经过该代码就不用一个一个写不少bean

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.eluzhu.rms.mapper"/>
    </bean>

 

而@Component在此隐性建立bean,不须要你管理对象,而直接交给spring管理。

这样对于效率的提升是很是有帮助的。

我之因此喜欢SpringMVC的最大缘由,是由于简单明了轻量化,struts2的话,当初学习的时候,感受有很多难度,固然了,学习完后,用的多,习惯就好,可是每次比较烦躁的就是要增长一个相似于Controller做用的类,我都必需要配置一个struts2相关的xml文件。时间久了,CV大法便可搞定,当后来接触SpringMVC时,就发现我不再想用struts2了。SpringMVC能够说是从Struts2演变而来并借助Spring的名气。

固然了,在校学习Java的同窗们,建议仍是把Struts2学好,毕竟Struts2的更面向对象。并且涉及很多设计模式。学好Struts2,对理解SpringMVC很是有帮助。

 

 

 

 

 

 

问题三:SpringMVC的配置文件关于注解配置,没有配置好致使本因返回JSON数据,最后却变成了XML。

如图所示:

解决办法:在spring-mvc.xml配置文件,添加以下内容便可解决:

 <!-- FastJson注入 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
            <!-- FastJson -->
            <bean id="fastJsonHttpMessageConverter"
                  class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <!-- 这里顺序不能反,必定先写text/html,否则ie下出现下载提示 -->
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

 

 

相关文章
相关标签/搜索