SpringMVC-基础

目录

MVC模式

SpringMVC工作原理

导入jar包

SpringMVC核心组件

从请求中获取到参数

Controller传递数据到JSP页面

拦截器

国际化


 

MVC模式

1.早期非MVC模式

      早期的Java Web开发中,统一将显示层、控制层、数据层的操作全部交给JSP 或者 JavaBean 来进行处理。如下:

       弊端如下:

1.耦合性高,JSP和Java Bean之间严重耦合,Java代码和HTML也耦合在一起
2.要求开发者不仅要掌握Java,还要掌握前端
3.前后端依赖严重,前端需要等待后端完成,后端也依赖前端完成,才能进行有效的测试
4.代码难以复用

2.早期MVC模式

        早期的MVC模式采用:Servlet + JSP + Java Bean。如下所示:

  • 请求流程

         用户的请求首先会到达Servlet,然后根据请求调用相应的Java Bean,并把所有的显示结果交给JSP去完成。

  • MVC概念

          MVC​​​​​​​是一种架构模式,将业务逻辑和页面展示分离,使程序分层、分工合作,既相互独立,又协同合作。

M(Model)

表示模型,模型就是数据(dao,bean)。

通常模型对象负责在数据库中存取数据。

V(View)

表示视图,就是JSP。

通常视图是依据模型数据创建的。

C(Controller)

表示控制器,控制器的作用就是用于处理数据(Model)和视图(View)。

调用业务逻辑产生合适的数据(Model),同时传递数据(Model)给视图层(View)呈现给用户

3.Spring MVC

 

SpringMVC工作原理

1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。

2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.

3.DispatcherServlet请请求提交到目标Controller

4.Controller进行业务逻辑处理后,会返回一个ModelAndView

5.DispatcherServlet查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象

6.视图对象负责渲染返回给客户端。

如下图所示:

 

导入jar包

     在Maven中导入jar包:

<!-- spring-webmvc(包含spring核心包) -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.7.RELEASE</version>
</dependency>
		

 

SpringMVC核心组件

DispatcherServlet          

含义 DispatcherServlet是前端控制器
作用

接收请求,响应结果,相当于转发器,降低了组件之间的耦合性

用户发送请求交给DispatcherServlet,DispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户请求,分发到具体对应的Controller,从而获取到需要的业务数据Model。然后Model再通过DispatcherServlet传递给View完成页面的呈现。

实质Spring MVC通过DispatcherServlet加载Spring容器,实现两者整合

          配置:在web.xml中进行servlet配置。要求:在容器启动的时候DispatcherServlet就要被实例化。

<servlet>
    <servlet-name>xxx</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <!-- contextConfigLocation指定使用spring容器 -->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:xxx.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>xxx</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

Controller

       配置方式如下:

  • 通过在spring容器中配置
<!-- controller的配置 -->
<bean id="controllerName" class="PackageName.ControllerClassName"></bean>
  • 通过注解方式配置

         注解方式直接在Controller类上添加@Controller即可。如下:

@Controller
public class LoginController {
    //...
}

HandlerMapping

含义HandlerMapping表示处理器映射器
作用

HandlerMapping负责根据用户请求的URL找到Handler(处理器),帮助DispatcherServlet找到对应的Controller。

SpringMVC提供了多种不同的映射器实现不同的映射方式,例如:配置文件方式、实现接口方式。注解方式等。

      配置方式如下:

  • 在spring容器中配置
<!-- handlerMapping的配置 -->
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mapping">
        <props>
            <!-- key表示请求的url地址,controllerName表示该url地址要找的controller-->
            <prop key="xxx.do">controllerName</prop>
        </props>
    </property>
</bean>
  • 通过注解方式配置

         通过使用@RequestMapping("参数")方式。如下:

@Controller
public class LoginController {

    @RequestMapping("login.do")
    public ModelAndView login(String uname, String upwd) {
        ModelAndView mav = new ModelAndView();
        System.out.println(uname);
        System.out.println(upwd);
        if ("admin".equals(uname) && "123".equals(upwd)) {
            mav.setViewName("success");
        }else {
            mav.setViewName("login");
        }
        return mav;
    }
}

ViewResolver

含义ViewResolver表示视图解析器
作用

根据逻辑视图名解析成真正的视图View

ViewResolver负责将处理结果生成View视图,ViewResolver首先根据逻辑视图名解析成具体的页面地址,然后对View进行渲染,将处理结果通过页面展示给用户;SpringMVC提供了很多类型View视图,包括:jstlView、freemarkerView、pdfView、jsp、html等。

     配置:在spring容器中配置

<!-- viewResolver的配置 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 拼接出一个jsp地址:/WEB-INF/xxx.jsp -->
    <!-- prefix表示前缀,suffix表示后缀-->
    <property name="prefix" value="/WEB-INF/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>

ModelAndView

       ModelAndView是SpringMVC对Model的一种表示形式。SpringMVC中有Model、Map,但是SpringMVC都会将其转化为ModelAndView。

 

从请求中获取到参数

     传递请求到Controller时,如果包含参数,有如下方式获取到传递的参数数据:

  • 1.给方法形参添加一个HttpServletRequest

         给方法参数传递一个HttpServletRequest,然后从request中获取到参数。

@RequestMapping("toLogin.do")
public String login(HttpServletRequest request) {
    String uname = request.getParameter("uname");
    String upwd  = request.getParameter("upwd");
		
    if("admin".equals(uname) && "123456".equals(upwd)) {
        return "success"; // 转发到success.jsp
    }else {
        return "jsp/login";  // 转到login.jsp
    }		
}
  • 2.使用注解

         请求中的参数key和方法的形参名字不一样, 需要使用注解,说明请求的中的参数和方法的参数的对应关系。

@RequestMapping("toLogin.do")
public String login(@RequestParam("uname")String name, @RequestParam("upwd")String pwd) {
    if("admin".equals(name) && "123456".equals(pwd)) {
        return "success"; // 转发到success.jsp
    }else {
        return "jsp/login";  // 转到login.jsp
    }		
}
  • 3.让方法的形参名字和请求中数据的key的名字保持一致

           方法的形参名字和请求中数据的key的名字保持一致,那么会自动将请求数据key对应的value值,赋值到对应的形参中。

@RequestMapping("toLogin.do")
public String login(String uname, String upwd) {
    if("admin".equals(uname) && "123456".equals(upwd)) {
        return "success"; // 转发到success.jsp
    }else {
        return "jsp/login";  // 转到login.jsp
    }		
}
  • 4.方法的形参设置成一个对象

           如果请求中数据key和对象的属性名字一样,那么会将传递的数据封装为一个对象。注意:该对象必须有getter和setter方法。

@RequestMapping("abc.do")
public String login(User  user) {
    //System.out.println(user.getUname());
    //System.out.println(user.getUpwd());
    if("admin".equals(user.getUname()) && "123456".equals(user.getUpwd())) {
        return "success"; // 转发到success.jsp
    }else {
        return "jsp/login";  // 转到login.jsp
    }
}

 

Controller传递数据到JSP页面

1.通过ModelAndView(不推荐)

@RequestMapping("toLogin.do")
public ModelAndView  login(User  user) {
    ModelAndView  mav = new ModelAndView();
    Map<String, Object> map = mav.getModel();
    if("admin".equals(user.getUname()) && "123456".equals(user.getUpwd())) {
        map.put("msg", "登录成功");
        mav.setViewName("success");
    }else {
        map.put("msg", "登录失败");
        mav.setViewName("success");
    }
    return mav;
}

2.通过ModelMap

        在jsp页面中可以使用el表达式获取到这个参数值。

@RequestMapping("toLogin.do")
public String login(User user, ModelMap map) {
    if("admin".equals(user.getUname()) && "123456".equals(user.getUpwd())) {
        map.put("msg", "登录 success。。。。。。。。");
        return "success"; // 转发到success.jsp
    }else {
        map.put("msg", "登录 fail 。。。。。。。。");
        return "success"; 
    }
}

3.通过Model

          在jsp页面中可以使用el表达式获取到这个参数值。

@RequestMapping("toLogin.do")
public String login(User user, Model model) {
    if("admin".equals(user.getUname()) && "123456".equals(user.getUpwd())) {
        model.addAttribute("msg", "login success,,,,,,,"); 
        return "success"; // 转发到success.jsp
    }else {
        model.addAttribute("msg", "login fail,,,,,,,");
        return "success"; 
    }
}

 

拦截器

1.使用

  • 定义类继承于HandlerInterceptorAdapter

         重写其中的方法:

public class FirstInterceptor extends HandlerInterceptorAdapter{
    /**
     * Controller中的方法执行之前,要先访问preHandle方法
     * 返回true表示通过请求,返回false表示不通过请求
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
        System.out.println("preHandle方法被执行");
        return false;
    }
	
    /**
     * 在Controller中的方法执行之后,执行该方法
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle方法被执行");
    }
	
    /**
     * 请求处理结束之后,执行该方法
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                                   Object handler, Exception ex)throws Exception {
        System.out.println("afterCompletion方法被执行");
    }
	
    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, 
                             HttpServletResponse response, Object handler)throws Exception {
    System.out.println("afterConcurrentHandlingStarted方法被执行");
    }	
}
  • 在Spring的容器中进行配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
	
    <context:component-scan base-package="day4"></context:component-scan>
	
    <!-- viewResolver的配置 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
	
    <!-- 拦截器的配置 -->
    <mvc:interceptors>
        <!-- 可以配置多个拦截器 -->
        <mvc:interceptor>
            <!-- 匹配需要被拦截的请求路径:/**代表拦截所有的请求 -->
            <mvc:mapping path="/**"/>
            <!-- exclude-mapping:表示不被拦截的请求路径,可以配置多个-->
            <mvc:exclude-mapping path="/user/toLogin.do"/>
            <mvc:exclude-mapping path="/user/login.do"/>
            <bean class="day4.FirstInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
		
</beans>

 

国际化

1.定义

     国际化指的是,一套软件适合所有语言的人使用,根据地区匹配显示对应的语言(中文地区显示中文,英文地区显示英文)。

2.实现国际化步骤

  • 1.配置不同语言的属性文件

          将页面显示的内容,使用支持国际化的属性文件中的内容显示。如下所示:配置了中文和英文的属性文件:

          英文属性文件:message_en_US.properties

welcomeInfo=Welcome to use Student Management Syatem
username=user name
password=user pwd
rember=is rember?
login=login
loginResult=login result is:
success=success
fail=fail

         中文属性文件:message_zh_CH.properties

welcomeInfo=\u6B22\u8FCE\u4F7F\u7528\u5B66\u751F\u7BA1\u7406\u7CFB\u7EDF
username=\u7528\u6237\u540D
password=\u5BC6\u7801
rember=\u662F\u5426\u8BB0\u4F4F\u5BC6\u7801\uFF1F
login=\u767B\u5F55
loginResult=\u767B\u5F55\u7ED3\u679C\u4E3A
success=success
fail=fail
  • 2.在Spring的xml容器中进行国际化相关配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
    ...>
	
    <context:component-scan base-package="day5"></context:component-scan>
    ...
	
    <!-- 国际化相关配置 -->
    <!-- 规定id只能叫:messageSource -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <!-- name:表示属性名字  value:表示要引用的属性文件的名字 -->
        <!-- 引入英文配置文件 -->
        <property name="basename" value="message_en_US"></property>
    </bean>
	
</beans>
  • 3.在JSP页面中引入Spring 标签库,引入属性文件中的key对应的value
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="javax.servlet.http.Cookie" %>
<!-- 引入Spring标签库 -->
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<!--登录页面-->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>登录页面</title>
    <link rel="stylesheet" href="css/reset.css" />
</head>
<body>
    <div class="contian">
        <div class="disc"><spring:message code="welcomeInfo"></spring:message></div>
        <div class="cont">
            <form action="<%=request.getContextPath() %>/login.do" method="get">
                <div class="name_div">
                    <!-- 用户名 -->
                    <label for="user"><spring:message code="username"></spring:message></label>
                    <input class="int" type="text" name="uname" />
                </div>
                <div class="pwd_div">
                    <!-- 密码 -->
                    <label for="pwd"><spring:message code="password"></spring:message></label>
                    <input class="int" type="password" name="upwd" />
                </div>
                <div class="pwd_div">
                    <!-- 是否记住密码 -->
                    <input class="int" type="checkbox" name="remember" value="1" checked="checked"/>
                    <spring:message code="rember"></spring:message>
                </div>
                <!-- 登录 -->
                <input type="submit" value='<spring:message code="login"></spring:message>'></input>
            </form>
        </div>
    </div>
</body>
</html>
  • 4.在Controller的方法里面使用国际化传递参数

             需要使用到ResourceBundleMessageSource类,用于获取到属性文件中的key对应的value值。

@Controller
public class LoginController {
	//可以获取到属性文件中的Key
	@Resource
	private ResourceBundleMessageSource messageSource;
	
	@RequestMapping("toLogin.do")
	public String toLogin() {
		return "i18n_login";
	}
	
	/**
	 * 在方法中使用国际化,从配置文件中读取key
	 * @param model
	 * @param uname
	 * @param upwd
	 * @param locale
	 * @return
	 */
	@RequestMapping("login.do")
	public String login(Model model, String uname, String upwd, Locale locale) {
		if ("admin".equals(uname) && "123".equals(upwd)) {
			String success = messageSource.getMessage("success", null, locale);
			model.addAttribute("msg", success);
		}else {
			String fail = messageSource.getMessage("fail", null, locale);
			model.addAttribute("msg", fail);
		}
		return "result";
	}
}

3.运行结果

        使用英文配置文件,登录页面如下所示:

      跳转后的结果JSP页面如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<spring:message code="loginResult"></spring:message>:${msg } 
</body>
</html>

       输入正确的账号密码后结果页面显示如下:

 

 

 

 

 

 

 

 

 

 

 

参考:https://blog.csdn.net/luciferlongxu/article/details/80460580

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckyliuqs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值