简单的介绍下Spring MVC:一种轻量级的、基于mvc的web层应用框架;功能类似于struts2。
Spring MVC的常用组件:
- DispatherServlet:前端控制器(又称核心控制器)。
- Controller:处理器/页面控制器,是mvc中的c,控制逻辑转移到前端控制器。用于对请求的处理。
- HandlerMapping:请求映射到处理器,如果映射成功返回一个HandlerExecutionChain对象(包含一个hander处理器对象,多个HandlerInterceptor拦截器对象。由DispatcherServlet中调用,完成请求到具体的controller的映射)。
- ViewResolver:视图解析器,用来处理返回的页面。把逻辑视图解析为具体的的View。如InternalResourceViewResolver将逻辑视图名映射为JSP视图,通过controller执行完毕之后返回的字符串找到字符串对应的页面资源。
- LocalResolver:本地化、国际化。
- MultipartResolver:文件上传解析器。
- HanderExceptionResolver:异常处理器。
Spring mvc的Demo的实现步骤:
新建一个web工程,导入jar包.(maven使用依赖)。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
在web.xml中配置DispatherServlet。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>springmvc</display-name>
<!-- 配置springmvc核心控制器 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置DispatcherServlet的初始化参数:设置文件路径和文件名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classPath:springmvc.xml</param-value>
</init-param>
<!-- tomcat优先加载 ,数值越大(>0),越优先-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<!-- <url-pattern>/</url-pattern> 这样写会导致许多的静态资源被拦截器所拦截
解决方式1(只要一个mapping):<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.gif</url-pattern>
<url-pattern>/js/*</url-pattern>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
-->
<!-- 解决方式2:只拦截.do后缀的 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
在src或者resource下添加Spring MVC的配置文件springmvc.xml(文件名可以自定义)。
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd" >
<!-- 设置扫描组建的包 -->
<context:component-scan base-package="com.qf"></context:component-scan>
<!-- 配置解析器:
如何将控制器返回的字符串结果转换为一个物理的视图文件
-->
<bean id="internalResourceViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- prefix:前缀 suffix:后缀 拼接字符串 -->
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
写处理请求的处理器(java代码)。
package com.qf;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.qf.bean.User;
@Controller
public class TestSpringMVC {
// 用来注解映射的请求URL(类似于servlet的虚拟路径的配置)
//一般映射路径名称最好一致(可以不一致),利于辩识。
@RequestMapping(path = "/test1.do")
public String test1() {
System.out.println("this is test1");
// 返回的字符串会通过springmvc.xml中视图解析器进行拼接字符串,然后访问到jsp页面
//return "success";在跳转时默认是转发
//重定向写法,绝对路径,不在经过视图解析器
return "redirect:1.html";
}
}
//还有需要注解的使用,此处就不多列举了
Spring MVC的流程图:
客户端的请求–>核心控制器(DispatcherServlet)–>页面控制器(Controller)–>视图解析器(ViewResolver)
页面控制器能接受的请求方式:get,post,head,put,delete,options,trace等
注解有:@PostMapping @GetMapping
Spring MVC的数据流入:
//1.使用HttpServletRequest获取
@RequestMapping(path="/login1.do")
public String login1(HttpServletRequest request){
String name = request.getParameter("username");
String pwd = request.getParameter("password");
System.out.println(name+"--"+pwd);
return "success";
}
//2.@RequestParam注解
@RequestMapping(path="/login2.do")
public String login2(@RequestParam(value="username") String name,
@RequestParam(value="password") String pwd){
System.out.println(name+"--"+pwd);
return "success";
}
//3.入参数获取 是@RequestParam注解的简化版
@RequestMapping(path="/login3.do")
public String login3(String username,String password){
System.out.println(username+"--"+password+"--"+"3");
return "success";
}
/*4.@requestHeader 请求头中包含若干属性,通过该注解能将请求头中的属性值绑定到处理方法的入参数中*/
@RequestMapping(path="/handle.do")
public String handle(@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") String keepalive){
System.out.println(encoding+"--"+keepalive+"--"+"4");
return "success";
}
//5.@CookieValue 能获取到jessionid
@RequestMapping(path="/login4.do")
public String login4(@CookieValue("JSESSIONID") String id){
System.out.println(id);
return "success";
}
//6.pojo实体类(有级联关系)
@RequestMapping(path="/user.do")
public String testUser(User user){
System.out.println(user);
return "success";
}
//前端代码
<form action="user.do" method="post">
username:<input type="text" name="username" /><br/>
age:<input type="text" name="age" /><br/>
object.math:<input type="text" name="object.math" /><br/>
object.java: <input type="text" name="object.java" /><br/>
<input type="submit" value="submit" />
</form>
//7.Servlet的原生API作为参数
@RequestMapping(path="/ServletAPI.do")
public void testServletAPI(HttpServletResponse response,Writer out) throws Exception{
System.out.print(response);
out.writer("你好!")
}
//就是在servlet中的方法
@RequestMapping映射:
Spring MVC中@RequestMapping注解为控制器指定url请求。但是定义在类上和方法上是有区别的
- 标记在类上:提供初步的请求映射信息,相对于web应用的根目录
- 标记在方法上:提供进一步的细分信息,相对于标记在类上的url.真实的访问路径:类url+方法url
//真实的访问路径:springmvc/helloworld
<a href="springmvc/helloworld">test @RequestMapping</a>
@Controller //声明Bean对象,为一个控制器组件
@RequestMapping("/springmvc")
public class HelloWorldController {
@RequestMapping(value="/helloworld")
public String helloworld(){
System.out.print("hello");
return "success";
}
}
响应数据的输出
//1.ModelAndView(request作用域):处理方法的返回值类型为ModelAndView时,方法体即可通过改对象添加数据模型
@RequestMapping(path="/")
public ModelAndView testMAV(){
ModelAndView mv = new ModelAndView(){
//设置视图
mv.setViewName("success");
mv.addObject("键","值");
//最终返回一个mv对象,springmvc会读取数据模型和视图
return mv;
}
}
//前端页面接收
${requestScope.mv}
/*2.Map(request作用域):是在springmvc请求处理前创建的一个隐含对象,这个隐含对象可以提供给方法使用,就像操作作用域一样向map中添加键值对,在方法执行完毕时,springmvc会读取map中的值,自动调用request.setAttrbuite方法,把map中的数据同步到作用域中*/
@RequestMapping(path = "/toview3.do")
public String testMap(Map<String,Object> map){
map.put("name","张三");
map.put("age",1);
return "success";
}
//前端页面接收
${requestScope.map}
//Map,Model,ModelMap
public String testM(Map<String,Object> map,Model md,ModelMap mm){
map.put("map","map");
md.addAttribute("md","md");
mm.addAttribute("mm","mm");
System.out.print(map==md);//true
System.out.print(map==mm);//true
//System.out.print(map/md/mm.getClass().getName());//三者都打印出来的name一样属于同一个对象
return "success";
}
//前端页面接收
${requestScope.map}
${requestScope.md}
${requestScope.mm}
//@SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便于多个请求之间共享这个属性
@RequestMapping(path = "/toview5.do")
public String test5(Map<String, Object> map) {
// 假设要插入一个用户登录状态
map.put("islogin", true);
User user = new User();
user.setName("zz");
return "show";
}
//前端页面接收
${sessionScore.islogin}
${sessionScore.name}
//@ModelAttribute:方法入参标注该注解后,入参的对象就会放到数据模型中
@ModelAttribute
public void testModelAttribute(@RequestParam(name="username",required=false) String name ){
//这里也可以获取到前端的数据
System.out.print("testMA");
}
//@ModelAttribute注解标注的方法执行在处理用户请求的方法之前,所以也就不能在请求的方法中组装数据,再通过@@ModelAttribute进行返回
@ModelAttribute("list")//设置这个注解后可以直接在前端页面直接使用list(可以自定义)对象集合
public List<String> testMA(){
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
return list;
}
//前端输出:
${list}