SpringMVC初步学习

一、什么是SpringMVC

MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。
1模型:用于存储数据以及处理用户请求的业务逻辑。
2.视图:向控制器提交数据,显示模型中的数据。
3.控制器:根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有关结果交给哪个视图更新显示。

SpringMVC的工作流程
在这里插入图片描述
从上图 可总结出 Spring MVC 的工作流程如下:
1.客户端请求提交到 DispatcherServlet。
2.由 DispatcherServlet 控制器寻找一个或多个 HandlerMapping,找到处理请求的 Controller。
3.DispatcherServlet 将请求提交到 Controller。
4.Controller 调用业务逻辑处理后返回 ModelAndView。
5.DispatcherServlet 寻找一个或多个 ViewResolver 视图解析器,找到 ModelAndView 指定的视图。
视图负责将结果显示到客户端。

SpringMVC几大接口介绍
1.DispatcherServlet(前端控制器)
Spring MVC 所有的请求都经过 DispatcherServlet 来统一分发,在 DispatcherServlet 将请求分发给 Controller 之前需要借助 Spring MVC 提供的 HandlerMapping 定位到具体的 Controller。

2.HandlerMapping(处理器映射器)
HandlerMapping负责根据用户请求找到Handler即处理器,寻找URL所请求的HandlerMethod,找@RequestMapping() ,SpringMVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等 ,使用实现类DefaultAnnotationHandlerMapping实现 。

3.HandlerAdapter(处理器适配器)
实际调用HandlerMethod的组件. 通过HandlerAdapter对处理器进行执行,这是适配器模式的应用, 通过扩展适配器可以对更多类型的处理器进行执行,使用实现类AnnotationMethodHandlerAdapter

4.ViewResovler(视图解析器)
作用解析HandlerMethod返回值.把逻辑视图转换为需要调用的物理视图. 自定义视图:InternalResourceViewResolver ,负责将处理结果生成View视图,ViewResolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。

二、SpringMVC的使用

1.Spring MVC中@Controller和@RequestMapping的使用
@Controller 注解
Spring MVC 中使用 org.springframework.stereotype.Controller 注解类型声明某类的实例是一个控制器,其实就是使用@ComponentScan注解或者XML文件中<context:component-scan>j将标记有@Controller、@Service、@repository、@Component等注解的类注入到IOC容器中,作为Spring的Bean来管理。

@RequestMapping注解
可以注解类也可以注解方法,注解类时标注请求的路径,标注方法时表示将特定的URL映射到指定的方法。

使用示例:

先做一个简单的登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<p>用户登录</p>
<form action="/user/login" method="post">
    <input type="text" name="username" placeholder="用户名"/>
    <input type="password" name="password" placeholder="密码">
    <input type="submit" value="提交">
</form>
</body>
</html>
@Controller
 @RequestMapping("/user")
public class Test {
    @RequestMapping("/logintest")
    public String login(){
        return "/login.html";
    }
}

然后先启动SpringBoot的启动类

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

然后在浏览器上输入url,就可以显示登陆界面了
在这里插入图片描述
@RequestMapping可以修饰类,也可以修饰方法,如果修饰类了,那么在浏览器上输入全路径,例如以上的路径就是http://localhost:8080/user/logintest,如果不修饰类,就只需要输入方法上的路径http://localhost:8080/logintest就行了。
@RequestMapping还可以指定请求方法类型,默认情况下是Get方法,表示只对Get请求有效,

@RequestMapping(value = "/login", method = {RequestMethod.GET, RequestMethod.POST})

上面的Method参数表示可以支持Get和Post请求。

2.SpringMVC的转发和重定向

转发与重定向的区别:
1.重定向会发送两次请求,转发是一次request请求
2.重定向会改变url,转发不会
3.在Tomcat中重定向可以定向到外面的信息,比如百度,但是转发只能访问内部文件
4.重定向是会数据丢失,转发不会。

SpringMVC中转发的实现
在 Spring MVC 框架中,控制器类中处理方法的 return 语句默认就是转发实现,只不过实现的是转发到视图。示例代码如下:

 @RequestMapping("/register")
    public String register() {
        return "register";  //转发到register.jsp
    }

转发到另一个请求方法,示例如下:

 @RequestMapping("/forwardtest")
    public String login7(){
        return "forward:/user/logintest";
    }

此时当在浏览器输入http://localhost:8080/user/forwardtest,就会显示到登录页面了,url不会改变

SpringMVC的重定向的实现

 @RequestMapping("/redirecttest")
    public String login8(){
        return "redirect:/user/forwardtest";
    }

当在浏览器输入http://localhost:8080/user/redirecttest,url会自动跳转到http://localhost:8080/user/forwardtest

三、SpringMVC中参数的获取

先创建一个测试类

@Setter
@Getter
public class Duck {

    private String name;

    private Integer age;

    public Duck(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

@ResponseBody的作用:
这个注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。

这个注解表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用。

在使用@RequestMapping后,返回值通常解析为跳转路径。加上@responsebody后,返回结果直接写入HTTP response body中,不会被解析为跳转路径。比如异步请求,希望响应的结果是json数据,那么加上@responsebody后,就会直接返回json数据。

1.、通过处理请求方法的形参就可以获得参数

 @RequestMapping("/duck")
    @ResponseBody
    public Duck login9(Duck duck){
        System.out.println("姓名:"+duck.getName()+"&年龄:"+duck.getAge());
        return duck;
    }

此时控制台可以输出:

姓名:唐老鸭&年龄:28

2.通过 HttpServletRequest 接收请求参数

@RequestMapping("/duck1")
    @ResponseBody
    public Duck login10(HttpServletRequest request){
        String name=request.getParameter("name");
        String age= request.getParameter("age");
        return new Duck(name,Integer.parseInt(age));
    }

浏览器的显示:
在这里插入图片描述

3.通过 @PathVariable 接收 URL 中的请求参数
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
示例:

@RequestMapping("/duck2/{name}/{age}")
    @ResponseBody
    public Duck login10(@PathVariable() String name,@PathVariable String age){
        return new Duck(name,Integer.parseInt(age));
    }

在这里插入图片描述

4.通过 @RequestParam 接收请求参数
示例:

@RequestMapping("/duck3")
    @ResponseBody
    public Duck login11(@RequestParam String name,@RequestParam String age){
        return new Duck(name,Integer.parseInt(age));
    }

在这里插入图片描述
@RequestParam的使用

@RequestParam(value=”参数名”, required=true/false, defaultValue=””);

required:是否必须,默认为true,即请求中必须包含该参数,如果没有包含,将会抛出异常。

defaultValue:默认值,如果设置了该值,required 将自动设为 false,无论你是否配置了required,配置了什么值,都是 false;如果没有传该参数,就使用默认值(可选配置)

5.通过 @ModelAttribute 接收请求参数

@RequestMapping("/duck4")
    @ResponseBody
    public Duck login11(@ModelAttribute("duck") Duck duck){
        return duck;
    }

在这里插入图片描述
@ModelAttribute 的使用
在上述代码中“@ModelAttribute(“duck”)Duck duck”语句的功能有两个:
1.将请求参数的输入封装到 duck 对象中。
2.创建 Duck 实例。

以“duck”为键值存储在 Model 对象中,和“model.addAttribute(“duck”,duck)”语句的功能一样。如果没有指定键,会以驼峰式的实例对象作为键,例如DuckFrom->duckFrom。
被 @ModelAttribute 注解的方法将在每次调用该控制器类的请求处理方法前被调用。这种特性可以用来控制登录权限,当然控制登录权限的方法有很多,例如拦截器、过滤器等。

四、拦截器的使用

在开发一个网站时可能有这样的需求:某些页面只希望几个特定的用户浏览。对于这样的访问权限控制,应该如何实现呢?拦截器就可以实现上述需求。
在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,定义一个拦截器可以通过两种方式:一种是通过实现 HandlerInterceptor 接口。
HandlerInterceptor接口介绍:

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

通过实现HandlerInterceptor 接口,重写接口中的 3 个方法。有关这 3 个方法的描述如下:

preHandle 方法:该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作。

postHandle 方法:该方法在控制器的处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步的修改。

afterCompletion 方法:该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行,可以通过此方法实现一些资源清理、记录日志信息等工作。

代码示例:
1.创建拦截器实现HandlerInterceptor接口

public class LoginInterceptor implements HandlerInterceptor {
    /**
     * Controller类方法调用前,如果匹配到拦截器的url,就会调用preHandle进行处理
     * @param request
     * @param response
     * @param handler
     * @return true能够继续访问(可以调用Controller中的方法,或是访问某个页面)
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession(false);//获取session,如果没有,返回null
        if(session != null){
            Object user = session.getAttribute("user");
            if(user != null){
                return true;   //返回为true时,表示可以继续访问。
            }
        }
        response.sendRedirect("/login.html");//重定向到登录界面
        return false;
    }
}

二、配置拦截器,自定义配置类进行拦截器配置

public class MVCConfig implements WebMvcConfigurer {
    /**
     * 根据url进行拦截,调用配置的拦截器进行处理
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 除了/login.html,/user/login两个url请求,其他全部要被拦截
        // 所有的拦截器依次执行:
        // interceptor.preHandle()--->controller.映射方法()--->interceptor.postHandle()
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login.html")
                .excludePathPatterns("/user/login");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值