SpringMVC

Hello word(第一个SpringMVC项目)**

先创建一个web程序

a.导包

spring-aop.jar
spring-bean.jar
spring-context.jar
spring-core.jar
spring-web.jar

spring-webmvc.jar
commons-logging.jar

b.创建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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
</beans>

c.将servlet服务交给springmvc处理(对web.xml进行配置)

<?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" version="3.1">
  	<display-name>Student_SpringMVC</display-name>
	<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>springDispatcherServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
</web-app>

在这里插入图片描述
在这里插入图片描述

/ : 表示拦截一切请求

报错NoClassDefFoundError:缺少jar

(直接复制后面的东西百度就可以找出是哪一个jar包)

创建测试的JSP

index.jsp

  <body>
    <<a href="hello.do">first springmvc</a>
  </body>

hello.jsp

  <body>
    hello world !! <br>
  </body>

servlet层

SpringMVCHandler.java

package org.lanqiao.handler;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class SpringMVCHandler {
	
	@RequestMapping("hello.do")
	public String welcom(){
		
		return "hello";
	}
}

@Controller:注解方式注入,相当于在配置文件写bean
@RequestMapping("hello.do"):拦截指定的请求,并返回一个字符串

springmvc.xml文件配置

默认路径:/SpringMVCProject/WebContent/WEB-INF/springmvc.xml(了解)

指定springmvc配置文件的路径,如果要省略,必须放到 默认路径:
/WEB-INF/servetname的值-servlet.xml

/WEB-INF/springDispatcherServlet-servlet.xml

/WEB-INF/springDispatcherServlet-servlet.xml

/WEB-INF/AAA-servlet.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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	
	<!-- 扫描 有注解的包 -->
	<context:component-scan base-package="org.lanqiao.handler"></context:component-scan>
	
	<!--配置视图解析器(InternalResourceViewResolver)  -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>

</beans>

视图解析器:返回值添加前缀和后缀
在这里插入图片描述

RequestMapping映射

在类前加RequestMapping **

映射是 去匹配@RequestMapping注解,可以和方法名、类名不一致

如果在类前面加RequestMapping,则超链接href路径要先写类的RequestMapping
例:
SpringMVCHandler.java

@Controller
@RequestMapping(value="handler")
public class SpringMVCHandler {
	@RequestMapping("hello.do")
	public String welcom(){
		return "hello";//默认使用了请求转发的跳转方式
	}
}
<a href="handler/hello.do">first springmvc</a>
http://localhost:8080/Student_SpringMVC/handler/hello.do

return默认使用的是请求转发方式
重定向需要加:return "redirect:***
例:return "redirect:hello;

请求过滤(REST风格)

get、post、delete、put
普通浏览器只支持get、post方式,不支持delete、put

get、post方式过滤
通过method指定 请求方式(get  post  delete put)
	@RequestMapping(value="welcome",method=RequestMethod.POST)//映射
	@RequestMapping(value="welcome",method=RequestMethod.GET)
delete、put方式过滤(通过过滤器实现,了解)

在这里插入图片描述
过滤器对于请求的拦截是有条件的,约定:1、必须是隐藏域、2.name=“_method”、3、value=“DELETE/PUT”、4、初始请求方式为POST

a、增加过滤器

HiddenHttpMethodFilter

浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求,该过滤器为HiddenHttpMethodFilter。

web.xml(增加部分)

		<!-- 增加HiddenHttpMethodFilte过滤器:目的是给普通浏览器 增加 put|delete请求方式 -->
	<filter>
			<filter-name>HiddenHttpMethodFilte</filter-name>
			<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
	
	</filter>
	
	<filter-mapping>
			<filter-name>HiddenHttpMethodFilte</filter-name>
			<!--拦截一切请求-->
			<url-pattern>/*</url-pattern>
	</filter-mapping>
b.前端

	<form action="handler/testRest/1234" method="post">
		<input type="hidden"  name="_method" value="DELETE"/>
		<input type="submit" value="删">
	</form>
i:必须是post方式
ii:通过隐藏域 的value值 设置实际的请求方式 DELETE|PUT
c.控制器
	@RequestMapping(value="testRest/{id}",method=RequestMethod.DELETE)
		public String  testDelete(@PathVariable("id") Integer id) {
			System.out.println("delete:删 " +id);
			//Service层实现 真正的增
			return "success" ;//  views/success.jsp,默认使用了 请求转发的 跳转方式
		}
通过	method=RequestMethod.DELETE	匹配具体的请求方式

此外,可以发现 ,当映射名相同时@RequestMapping(value="testRest),可以通过method处理不同的请求。

原理
过滤器中 处理put|delete请求的部分源码:
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		HttpServletRequest requestToUse = request;

		if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
			String paramValue = request.getParameter(this.methodParam);
			if (StringUtils.hasLength(paramValue)) {
				requestToUse = new HttpMethodRequestWrapper(request, paramValue);
			}
		}

		filterChain.doFilter(requestToUse, response);
	}
原始请求:request,改请求默认只支持get post  header
但是如果 是"POST"  并且有隐藏域		<input type="hidden"  name="_method" value="DELETE"/>
则,过滤器 将原始的请求 request加入新的请求方式DELETE,并将原始请求 转为 requestToUse 请求(request+Delete请求)
最后将requestToUse 放入 请求链中, 后续再事情request时  实际就使用改造后的 requestToUse
参数过滤
		@RequestMapping(value="welcome",method=RequestMethod.POST,params= {"name=zs","age!=23","!height"})//映射
		public String  welcome() {
			return "success" ;//  views/success.jsp,默认使用了 请求转发的 跳转方式
		}
  • 请求必须是post请求
  • 必须有name参数,默认值是zs
  • 参数age不能是23,没有age参数也可以
  • 必须没有height参数
请求头约定(了解)
		@RequestMapping(value="welcome2",headers= {"Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Encoding=gzip, deflate"})
		public String  welcome2() {
			return "success" ;//  views/success.jsp,默认使用了 请求转发的 跳转方式
		}
  • 浏览器中是冒号,这里用等号
  • 头与头之间用逗号隔开

ant风格请求路径

ant风格的请求路径
?  单字符
 *  任意个字符(0或多个)
** 任意目录

获取动态参数

方法一
@RequestMapping(value="welcome5/{name}")
		public String  welcome5(@PathVariable("name") String name ) {
			System.out.println(name);
			
			return "success" ;//  views/success.jsp,默认使用了 请求转发的 跳转方式
		}
  • @RequestMapping(value=“welcome5/{name}”)接收前台传过来的参数name
    前端:1234就是name的值
<form action="handler/testRest/1234" method="post">
		<input type="submit" value="">
	</form>
  • @RequestMapping将接收到的参数传入方法中注解@PathVariable(“name”)修饰的参数
方法二

直接获取表单中name属性为uname的value的值

@RequestMapping(value="testParam")
//required=false设置传入参数不是必须的
		public String  testParam(@RequestParam("uname") String name,@RequestParam(value="uage",required=false,defaultValue="23") Integer age) {
//			String name = request.getParameter("uname");
			
			System.out.println(name);
			System.out.println(age);
			return "success" ;//  views/success.jsp,默认使用了 请求转发的 跳转方式
		}
  • 普通传值:@RequestParam
public String  welcome5(@PathVariable("name") String name ) 
  • ant风格传值:@PathVariable(路径传值)
public String  testParam(@RequestParam("uname") String name)
使用对象接收参数(重要)
使用对象(实体类Student)接受请求参数

在SpringMVC中使用原生态的Servlet API  :HttpServletRequest :直接将 servlet-api中的类、接口等 写在springMVC所映射的方法参数中即可:
		@RequestMapping(value="testServletAPI")
		public String testServletAPI(HttpServletRequest  request,HttpServletResponse response) {
//			request.getParameter("uname") ;
			System.out.println(request);
			return "success" ;
		}

例:
JSP:

<form action="handler/testObjectProperties" method="post">
		id:<input name="id" type="text" />
		name:<input name="name" type="text" />
		家庭地址:<input name="address.homeAddress" type="text" />
		学校地址:<input name="address.schoolAddress" type="text" />
		<input type="submit" value="">
	</form>

student.java

package org.lanqiao.entity;

public class Student {
	private int id;
	private String name;
	private Address address ;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	
}	

Address.java

package org.lanqiao.entity;

public class Address {
	private String homeAddress ; 
	private String schoolAddress ;
	public String getHomeAddress() {
		return homeAddress;
	}
	public void setHomeAddress(String homeAddress) {
		this.homeAddress = homeAddress;
	}
	public String getSchoolAddress() {
		return schoolAddress;
	}
	public void setSchoolAddress(String schoolAddress) {
		this.schoolAddress = schoolAddress;
	}
	
}

ServletAPI(req、resp)

在这里插入图片描述

required=false设置传入参数不是必须的
  • 设置默认值: defaultValue=“23”

通过注解获取头信息

获取请求头信息 @RequestHeader
public String  testRequestHeader(@RequestHeader("Accept-Language")  String al  ) {
		
通过@RequestHeader("Accept-Language")  String al   获取请求头中的Accept-Language值,并将值保存再al变量中 
获取cookie的值
通过mvc获取cookie值(JSESSIONID)
@CookieValue 
(前置知识: 服务端在接受客户端第一次请求时,会给该客户端分配一个session (该session包含一个sessionId)),并且服务端会在第一次响应客户端时 ,请该sessionId赋值给JSESSIONID 并传递给客户端的cookie中

@RequestMapping(value="testCookieValue")
		public String  testCookieValue(@CookieValue("JSESSIONID") String jsessionId) {
			System.out.println( jsessionId);
			return "success" ;//  views/success.jsp,默认使用了 请求转发的 跳转方式
		}

处理模型数据

如果跳转时需要带数据:V、M,则可以使用以下方式:
ModelAndView、ModelMap  、Map、Model   -数据放在了request作用域 

@SessionAttributes、@ModelAttribute

示例:
public String testModel(Model model|	Map<String,Object> m) {

m.put(x,".."); 就会将x对象 放入request域中


如何将上述数据放入session中?@SessionAttributes(..)

@ModelAndView (☆☆☆☆)

		@RequestMapping(value="testModelAndView")
		public ModelAndView testModelAndView() {//ModelAndView:既有数据,又有视图
			//ModelAndView:Model -M     View-V
			ModelAndView mv = new ModelAndView("success");//view:  views/success.jsp 
			
			Student student = new Student() ;
			student.setId(2);
			student.setName("zs");
			
			mv.addObject("student", student);//相当于request.setAttribute("student", student);
			return mv;
		}

ModelAndView mv = new ModelAndView(“success”):设置跳转的地址
mv.addObject(“student”, student);//相当于request.setAttribute(“student”, student);

传递的数据(ModelMap 、Map、Model)

**数据都是放在了request作用域 **
**记:ModelMap **

@RequestMapping(value="testModelMap")
		public String testModelMap(ModelMap mm) {//success
			
			Student student = new Student() ;
			student.setId(2);
			student.setName("zs");
			
			mm.put("student2", student);//request域
			
			return "success";  //view
		}
		
		@RequestMapping(value="testMap")
		public String testMap(Map<String,Object> m) {
			
			Student student = new Student() ;
			student.setId(2);
			student.setName("zs");
			m.put("student3", student);//request域
			
			return "success";
		}
		
		@RequestMapping(value="testModel")
		public String testModel(Model model) {
			
			Student student = new Student() ;
			student.setId(2);
			student.setName("zs");
			model.addAttribute("student4",student);//request域
			return "success";
		}
传递数据时放在session中

在class前添加注解:@SessionAttributes(…)

//接口/类    注解   配置
//@SessionAttributes(value="student4")  //如果要在request中存放student4对象,则同时将该对象 放入session域中
//@SessionAttributes(types= {Student.class,Address.class})  //如果要在request中存放Student类型的对象,则同时将该类型对象 放入session域中(数组类型)
@Controller
@RequestMapping(value="handler") //映射
public class SpringMVCHandler {

@SessionAttributes(value=“student4”) //如果要在request中存放student4对象,则同时将该对象 放入session域中
@SessionAttributes(types= {Student.class,Address.class}) //如果要在request中存放Student类型的对象,则同时将该类型对象 放 入session

@ModelAttribute (慎用)

@ModelAttribute  在请求 该类的各个方法前 均被执行的设计是基于一个思想:一个控制器 只做一个功能
  • i.经常在 更新时使用
  • ii.在不改变原有代码的基础之上,插入一个新方法。
  • 在任何一次请求前,都会先执行@ModelAttribute修饰的方法

在这里插入图片描述
jsp

	<form action="handler/testModelAttribute" method="post">
		编号:<input name="id" type="hidden" value="31" />
		姓名:<input name="name" type="text" />
		<input type="submit" value="修改">
	</form>

注:@ModelAttribute先查询出student的值放入前台即将传入的参数中,然后前台传入参数,参数就更新了一遍

通过@ModelAttribute修饰的方法 ,会在每次请求前先执行;
并且该方法的参数map.put()可以将 对象 放入 即将查询的参数中;
必须满足的约定:
map.put(k,v) 其中的k 必须是即将查询的方法参数 的首字母小写
testModelAttribute(Student xxx)  ,即student;
如果不一致,需要通过@ModelAttribute声明。如下:
	@ModelAttribute//在任何一次请求前,都会先执行@ModelAttribute修饰的方法
		public void queryStudentById(Map<String,Object> map) {
			//StuentService stuService = new StudentServiceImpl();
			//Student student = stuService.queryStudentById(31);
			//模拟调用三层查询数据库的操作
			Student student = new Student();
			student.setId(31);
			student.setName("zs");
			student.setAge(23);
			map.put("stu", student) ;//约定:map的key 就是方法参数 类型的首字母小写
		}

		//修改:Zs-ls
		@RequestMapping(value="testModelAttribute")
		public String testModelAttribute(@ModelAttribute("stu")Student student) {
			student.setName(student.getName());//将名字修改为ls
			System.out.println(student.getId()+","+student.getName()+","+student.getAge());
			return "success";
		}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值