ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringMVC

2022-09-12 18:34:06  阅读:198  来源: 互联网

标签:index return RequestMapping SpringMVC 请求 public String


 

1、SpringMVC

  1. 什么是MVC

    MVC是一种软件的构想将软 件按照模型、视图、控制器来划分

    M:Model 模型, 指的是JavaBean 实体Bean和业务处理Bean(实体类和Dao、Service)

    V:View 视图, 指Html或者JSP等页面

    C:Controller 控制器,值工程中的Servlet,作用接收请求、响应请求

    MVC工作流程:

    用户通过视图发生请求到服务器,在服务器中被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller在根据请求处理的结果找到相应的View视图层,渲染数据后最终响应给游览器

2.什么是SpringMVC

SpringMVC是Spring的一个后续产品,是Spring的一个子模块,是Spring为表述层开发提供的一整套完备的解决方案

3.SpringMVC的特点

  • Spring家族原生产品,与IOC容器等基础设施无缝对接
  • 基于原生的Servlet,通过功能强大的DispatchServlet,对请求和响应进行统一处理
  • 代码清晰简洁
  • 性能卓越

2、HelloWorld

web.xml配置

spring中要求配置文件位于recesouces下,则可以在web.xml的servlet配置中,配置init-param指定配置文件的位置,如果没有配置init-param,则需要在WEB-INF下创建名称为[servlet-name]-servlet.xml的配置文件

<!--    1.配置控制器 DispatcherServlet-->
<servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!-- 指定SpringMVC配置文件的位置 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springMVC.xml</param-value>
    </init-param>
    <!-- 指定当前servlet的启动顺序 -->
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <!-- "/" 所有的请求(不包括.jsp),交由控制器DispatcherServlet去处理 -->
    <!-- "/*" 所有的请求(包括.jsp) -->
    <url-pattern>/</url-pattern>
</servlet-mapping>
springMVC.xml
<!--    1.组件加载-->
<context:component-scan base-package="com.potato.controller"/>
<!--    2.静态资源处理  需要和 <mvc:annotation-driven />   一起使用-->
<mvc:default-servlet-handler />
<!--    3.开启mvc注解驱动-->
<mvc:annotation-driven />
<!--    4.视图配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/static/html/" />
    <property name="suffix" value=".jsp" />
</bean>
HelloController.java
@Controller
@RequestMapping("/test")
public class HelloController {

    @RequestMapping("/index")
    public String index() {
        return "index";
    }

    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }
}

index.jsp

在/WEB-INF/static/html/下创建index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<h1>首页</h1>
<a href="${pageContext.request.contextPath}/hello">跳转</a>
</body>
</html>

配置启动Tomacat 即可完成web项目的访问

3、 @ReuqestMapping 注解

用于标识类或者方法
@Controller
@RequestMapping("/test")
public class HelloController {

    @RequestMapping("/index")  //访问路径为 /test/index
    public String index() {
        return "index";
    }

    @RequestMapping("/error")  //访问路径为 /test/error
    public String error() {
        return "error";
    }
}
@ReuqestMapping 属性值:
  • value: 通过请求路径匹配请求映射。可以是一个数组,表示该请求映射可以处理多个请求地址

  • method:通过请求方式匹配请求映射,请求方式 get/post/delete/put

  • params:通过请求参数匹配请求映射

  • headers:通过请求头匹配请求映射


@Controller
@RequestMapping("/test")
public class HelloController {
 	// value
    // 可以处理 /test/index 和 /test/main  请求
    @RequestMapping(value = {"index", "main"})
    public String index() {
        return "index";
    }

    // method
    // 只能处理 /test/index2  并且 请求方式为GET的请求
    @RequestMapping(value = "index2", method = RequestMethod.GET)
    public String index2() {
        return "index";
    }

    // params
    // 只能处理 /test/index3  并且 携带username参数,password参数的值必须是123456,age参数不能等于20,不允许有sex参数
    @RequestMapping(value = "index3", params = {"username", "password=123456", "age!=20", "!sex"})
    public String index3() {
        return "index";
    }

    //headers
    // 只能处理 /test/index4  并且 请求头的Host值必须为localhost:8080
    @RequestMapping(value = "index3", headers = {"Host=localhost:8080"})
    public String index4() {
        return "index";
    }

}
ant风格,路径规则、匹配

“?” :表示任意单个字符

“*” :表示任意0个或多个字符

“**” :表示任意一层或多层目录

//注意:在使用 ”**“时,只能使用 /**/xxx 的形式
// 表示无论是 /aat/test 或者 /abt/test、/act/test 等等请求,都可以匹配到当前映射方法
@RequestMapping("/a?t/test")  
public String test() {
    return "index";
}
restful风格,路径占位符、传值

路径占位符常用于restful风格,在响应的@RequestMapping注解的value属性中通过占位符{xxx}表示要传输的数据,在通过@PathVarlable注解获取占位符中的值

/**  3. restful风格 */
//在@RequestMapping注解的value属性中通过占位符{xxx}表示要传输的数据,在通过@PathVarlable注解获取占位符中的值
@RequestMapping("/restful/{id}/{pageIndex}")
public String restful(@PathVariable("id") String id,@PathVariable("pageIndex") Integer pageIndex) {
    System.out.println("id:"+id);
    System.out.println("pageIndex:"+pageIndex);
    return "index";
}
派生注解

@GetMapping、@PostMapping、@DeleteMapping、@PutMapping

4、获取请求数据

原生ServletAPI获取请求参数
控制器方法形参获取请求参数
@RequestParam
@RequesHeader
@CookieValue
通过POJO获取请求参数

解决请求乱码问题

/**
* 1.原生ServletAPI获取请求参数
*/
@RequestMapping("index")
public String index(HttpServletRequest request) {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println("username:" + username);
    System.out.println("password:" + password);
    return "index";
}

/**
* 2.控制器方法形参获取请求参数,请求参数名和形参名 必须要一致
*/
@RequestMapping("index2")
public String index2(String username, String password) {
    System.out.println("username:" + username);
    System.out.println("password:" + password);
    return "index";
}

/**
* 3.@RequestParam, 请求参数名和形参名 不一致
* value/name: 请求参数的名称,name和value两个属性基本是等价的,
* required:当前参数是否必须存在
* defaultValue:当前参数的默认值
*/
@RequestMapping(value = "index3")
public String index3(@RequestParam("user_name") String username) {
    System.out.println("username:" + username);
    return "index";
}
/**
* 4.@RequestHeader 获取请求头信息
* 和@RequestParam 一样的使用方法
*/
@RequestMapping(value = "index4")
public String index4(@RequestHeader("Host") String host) {
    System.out.println("host:" + host);
    return "index";
}

/**
* 5.@CookieValue 获取cookie数据
* 和@RequestParam 一样的使用方法
*/
@RequestMapping(value = "index5")
public String index5(@CookieValue("JSESSIONID") String JSESSIONID) {
    System.out.println("JSESSIONID:" + JSESSIONID);
    return "index";
}

/**
* 6.通过POJO获取请求参数
* 请求参数的名称和POJO类对象的属性名 要一致
*/
@RequestMapping(value = "index6")
public String index6(User user) {
    System.out.println(user);
    return "index";
}
解决乱码

get请求乱码 由tomcat照成,修改tomcat的配置文件

post乱码 配置CharacterEncodingFilter

<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

4、域对象数据共享

1.ServletAPI向request域对象共享数据
2.ModelAndView向request域对象共享数据
3.Model向request域对象共享数据
4.Map向request域对象共享数据
5.ModelMap向request域对象共享数据
6.Model、ModelMap、Map的关系
7.向session域对象共享数据
8.向application域对象共享数据
//1.ServletAPI向request域对象共享数据
@RequestMapping("/testServletApi")
public String testServletApi(HttpServletRequest request) {
    request.setAttribute("testRequestScope", "向域对象中共享的数据");
    return "index";
}

//2.ModelAndView向request域对象共享数据
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(ModelAndView mav) {
    // 向域对象中添加数据
    mav.addObject("testRequestScope", "向域对象中共享的数据");
    // 跳转的视图页面
    mav.setViewName("index");
    return mav;
}

//3.Model向request域对象共享数据
@RequestMapping("/testModel")
public String testModel(Model model) {
    model.addAttribute("testRequestScope", "向域对象中共享的数据");
    return "index";
}

//4.Map向request域对象共享数据
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) {
    map.put("testRequestScope", "向域对象中共享的数据");
    return "index";
}

//5.ModelMap向request域对象共享数据
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap) {
    modelMap.addAttribute("testRequestScope", "向域对象中共享的数据");
    return "index";
}

//6.Model、ModelMap、Map的关系  都是BindingAwareModelMap
//    public interface Model
//    public class ModelMap extends LinkedHashMap<String, Object>
//    public class ExtendedModelMap extends ModelMap implements Model
//    public class BindingAwareModelMap extends ExtendedModelMap

//7.向session域对象共享数据
@RequestMapping("/testSessionScopeByServletApi")
public String testSessionScopeByServletApi(HttpSession session) {
    session.setAttribute("testSessionScope", "向域对象中共享的数据");
    return "index";
}

//8.向application域对象共享数据
@RequestMapping("/testApplicationScopeByServletApi")
public String testApplicationScopeByServletApi(HttpSession session) {
    ServletContext servletContext = session.getServletContext();
    servletContext.setAttribute("testApplicationScope", "向域对象中共享的数据");
    return "index";
}

5、视图

转发视图 InternalResourceView
重定向视图 RedirectView
@Controller
@RequestMapping("/test")
public class ViewController {
    
    @RequestMapping("/index")
    public String index() {
        return "index";
    }

    //    转发视图,游览器发送了一次请求  请求地址不变
    @RequestMapping("testForward")
    public String testForward() {
        return "forward:/test/index";
    }

    //    重定向视图,游览器发送了两次请求  请求地址改变
    @RequestMapping("testForward")
    public String testRedirect() {
        return "redirect:/test/index";
    }
} 
视图控制器 InternalResourceViewResolver
路径只是为了跳转页面 mvc:view-controller
<!--    
当访问路径仅仅只是为了跳转页面,可以通过配置 mvc:view-controller
但是配置此标签后,其他控制器将失效,因此还需要配置 <mvc:annotation-driven/>
-->
<mvc:view-controller path="/" view-name="index"/>
<mvc:annotation-driven/>

6、HttpMessageConverter 报文信息转换器

HttpMessageConverter :将请求报文转换为java对象,或 将java对象转换为响应报文

HttpMessageConverter提供两个注解和两个类型:

@RequestBody,@ResponseBody,RequestEntity,ResponseEntity,@RestController

@RequestBody

将请求报文(请求体)转换为java对象

//    @RequestBody,
@RequestMapping("form")
public String request(@RequestBody String formData) {
    //  表单的数据以JSON字符串 的形式赋值给formData
    System.out.println(formData);
    return "success";
}
@ResponseBody

将java对象转换为响应报文(响应体)

//    @ResponseBody
//此处响应的"success" 不在作为视图进行解析,而是直接作为响应体返回给客户端
//如果响应的数据是一个java对象类型的  则需要导入json依赖,则返回的java对象自动转换为json对象
@ResponseBody
@RequestMapping("response")
public String response(){
    return "success";
}
RequestEntity

可以接受整个请求报文,包括请求头和请求体

//    RequestEntity,
@RequestMapping("request2")
public String request2(RequestEntity<String> request) {
    // 获取请求头信息
    HttpHeaders headers = request.getHeaders();
    // 获取请求体信息
    String body = request.getBody();

    return "success";
}
ResponseEntity

ResponseEntity用于控制方法的返回值类型,该控制器方法的返回值就是响应到游览器的响应报文

(也就是自定义响应报文)

@RestController

@RestController 替代 @Controller

表示当前控制器所有方法返回的结果 都是响应体,不是视图

7、文件下载、上传

文件下载

通过ResponseEntity 进行文件下载

@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
    //获取ServletContext对象
    ServletContext servletContext = session.getServletContext();
    //获取服务器中文件的真实路径
    String realPath = servletContext.getRealPath("/static/img/1.jpg");
    //创建输入流
    InputStream is = new FileInputStream(realPath);
    //创建字节数组
    byte[] bytes = new byte[is.available()];
    //将流读到字节数组中
    is.read(bytes);
    //创建HttpHeaders对象设置响应头信息
    MultiValueMap<String, String> headers = new HttpHeaders();
    //设置要下载方式以及下载文件的名字
    headers.add("Content-Disposition", "attachment;filename=1.jpg");
    //设置响应状态码
    HttpStatus statusCode = HttpStatus.OK;
    //创建ResponseEntity对象
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
    //关闭输入流
    is.close();
    return responseEntity;
}
文件上传

要求form表单的请求方式必须为post,并且添加属性enctype=“multipart/form-data”

SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息

上传步骤:

a>添加依赖

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

b>在SpringMVC的配置文件中添加配置:

<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

c>控制器方法:

@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
    //获取上传的文件的文件名
    String fileName = photo.getOriginalFilename();
    //处理文件重名问题
    String hzName = fileName.substring(fileName.lastIndexOf("."));
    fileName = UUID.randomUUID().toString() + hzName;
    //获取服务器中photo目录的路径
    ServletContext servletContext = session.getServletContext();
    String photoPath = servletContext.getRealPath("photo");
    File file = new File(photoPath);
    if(!file.exists()){
        file.mkdir();
    }
    String finalPath = photoPath + File.separator + fileName;
    //实现上传功能
    photo.transferTo(new File(finalPath));
    return "success";
}

8、拦截器

1.拦截器的配置

SpringMVC中的拦截器用于拦截控制器方法的执行

SpringMVC中的拦截器需要实现HandlerInterceptor接口,重写preHandle方法

public class FirstInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 拦截后进行逻辑处理的内容  返回true 代表放行,返回false 表示拦截
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置:

<mvc:interceptors>
    <!--        指定规则进行拦截-->
    <mvc:interceptor>
        <!--  拦截所有请求但是不包括 "/test" 请求   /* 表示只有一层路径  /**表示任意多层路径-->
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/test"/>
        <!--  拦截请求后 进行处理的类-->
    	<bean id="firstInterceptor" class="com.potato.interceptor.FirstInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>
2.拦截器的三个抽象方法

SpringMVC中的拦截器有三个抽象方法:

preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法

postHandle:控制器方法执行之后执行postHandle()

afterComplation:处理完视图和模型数据,渲染视图完毕之后执行afterComplation()

3.多个拦截器的执行顺序

a>若每个拦截器的preHandle()都返回true

此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:

preHandle()会按照配置的顺序执行,而postHandle()和afterComplation()会按照配置的反序执行

b>若某个拦截器的preHandle()返回了false

preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterComplation()会执行

客户端–> 过滤器 --> DispatcherServlet --> 拦截器 -->Controller

9、异常处理器

1.基于配置的异常处理
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--
                prop的键表示 需要进行处理的异常
                prop的值表示 若出现异常时,需要跳转到的视图名称
             -->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
    <!--
        exceptionAttribute属性设置一个值,将异常信息在 请求域 中进行共享,通过ex可以获取异常的信息内容
     -->
    <property name="exceptionAttribute" value="ex"/>
</bean>
2.基于注解的异常处理
@ControllerAdvice
public class ExceptionController {

    /**
     * @param ex 异常信息
     * @param model 把异常信息添加到域对象中
     * @return 异常页面
     */
    @ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
    public String exceptionMethod(Exception ex, Model model) {
        model.addAttribute(ex);
        return "error";
    }
}

10、注解配置SpringMVC

1.WebInit

创建初始化类,代替web.xml

在Servlet3.0+环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。
Spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又会查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。Spring3.2引入了一个便利的WebApplicationInitializer基础实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展了AbstractAnnotationConfigDispatcherServletInitializer并将其部署到Servlet3.0容器的时候,容器会自动发现它,并用它来配置Servlet上下文。

public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    /**
     * 指定spring的配置类
     *
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    /**
     * 指定SpringMVC的配置类
     *
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    /**
     * 指定DispatcherServlet的映射规则,即url-pattern
     *
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * 添加过滤器
     *
     * @return
     */
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceResponseEncoding(true);
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
    }
}

2.WebConfig

代替SpringMVC的配置文件

// 1.组件扫描  2.视图解析  3.view-controller  4.default-servlet-handler
// 5.mvc注解驱动  6.文件上传解析器  7.拦截器   8.异常处理

@Configuration
// 1.组件扫描
@ComponentScan("com.potato.controller")
// 5.mvc注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {


    //2.视图解析
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/static/");
        viewResolver.setSuffix(".jsp");
        registry.viewResolver(viewResolver);
    }

    //3.view-controller
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        WebMvcConfigurer.super.addViewControllers(registry);
    }

    //4.default-servlet-handler
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
        WebMvcConfigurer.super.configureDefaultServletHandling(configurer);
    }

    //6.文件上传解析器
    public CommonsMultipartResolver multipartResolver(CommonsMultipartResolver commonsMultipartResolver) {
        commonsMultipartResolver.setDefaultEncoding("UTF-8");
        commonsMultipartResolver.setMaxUploadSize(419430400);
        return commonsMultipartResolver;
    }

    //7.拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册自己定义的拦截器
        //registry.addInterceptor(new FirstInterceptor()).addPathPatterns("/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }

    //8.异常处理  可以使用注解配置代替
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties prop = new Properties();
        prop.setProperty("java.lang.ArithmeticException", "error");
        //设置异常映射
        resolver.setExceptionMappings(prop);
        //设置共享异常信息的键
        resolver.setExceptionAttribute("ex");
        resolvers.add(resolver);
        WebMvcConfigurer.super.configureHandlerExceptionResolvers(resolvers);
    }
}

11、SpringMVC的执行流程

  1. 用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获。

  2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI),判断请求URI对应的映射:

  3. 根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain执行链对象的形式返回。

  4. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。

  5. 如果成功获得HandlerAdapter,此时将开始执行拦截器的preHandler(…)方法【正向】

  6. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

  7. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象。

  8. 此时将开始执行拦截器的postHandle(…)方法【逆向】。

  9. 根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver进行视图解析,根据Model和View,来渲染视图。

  10. 渲染视图完毕执行拦截器的afterCompletion(…)方法【逆向】。

  11. 将渲染结果返回给客户端。

标签:index,return,RequestMapping,SpringMVC,请求,public,String
来源: https://www.cnblogs.com/yangyufu/p/16686868.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有