搭建一个简单的 springMVC 程序。
步骤:
(1)导入 jar 包
(2)在 web.xml 中配置 springMVC 的核心(前端)控制器 DispatcherServlet
<servlet>
<servlet-name>springMVCservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>springMVCservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
作用:加载 springMVC 的配置文件,在上述配置方式下,DispatchServlet 会自动加载配置文件,配置文件有默认的位置与名称:
默认位置:/WEB-INF/
下
默认名称:
,如上述配置方式的默认配置文件名为:springMVC-servlet.xml
当加载了配置文件之后,springMVC 会根据扫描到的组件找到控制层。
springMVC-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="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.xsd">
<context:component-scan base-package="com.mcc.springMVC">context:component-scan>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/">property>
<property name="suffix" value=".jsp">property>
bean>
beans>
(3)创建一个 POJO 类,在类上添加注解@Controller
,springMVC 就会将此类作为控制层,接收请求做出响应。
(4)在控制层中,在类或方法上使用@RequestMapping(value="/xxx")
注解,将请求路径与方法进行映射,当请求地址为:http://localhost:8080/工程路径/xxx
时(可以追加?key=value&key=value
),会自动调用该方法。
(5)处理请求的方法会返回一个字符串,该字符串即为视图名称,最终根据 springMVC 配置文件中配置的视图解析器实现页面跳转,跳转路径为:http://localhost:8080/工程路径/prefix+视图名称+suffix
package com.mcc.springMVC.hello;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller//将该类声明为控制类
public class DemoHello {
/**
* 假设请求地址为:http://localhost:8080/项目路径/hello
*/
//设置地址映射,即当请求地址为项目路径下的hello时,调用下面的方法
@RequestMapping("/hello")
public String Hello() {
System.out.println("success");
return "success";//设置视图名称,请求转发完成
//return "redirect:/success";//设置视图名称,请求重定向完成
}
}
注意:return “success”;
① 设置视图名称 ② 设置使用请求转发实现最终页面的跳转;
return "redirect:/success";
① 设置视图名称 ② 设置使用请求重定向实现最终页面的跳转。
测试:在浏览器地址栏中输入 http://localhost:8080/项目名称/hello,就会跳转到 WebContent/WEB-INF/view/success.jsp 页面。
名称 | 方式 |
---|---|
RequestMethod.GET | 查询 |
RequestMethod.POST | 添加 |
RequestMethod.PUT | 修改 |
RequestMethod.DELETE | 删除 |
package com.mcc.springMVC.hello;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller//将该类声明为控制类
@RequestMapping("upperView")
public class DemoHello {
/**
* 假设请求地址为:http://localhost:8080/项目路径/hello
* @RequestMapping(value,method,params,headers):设置请求映射,当请求地址与value值一致,并且其他参数的约束条件也满足时,
* 调用该注解下的方法接收请求做出响应,该注解可以加在类上和方法上,若类和方法上都添加了该注解,应该先访问类路径再访问方法路径。
* value:设置处理的请求地址
* method:设置处理的请求方式,RequestMethod.GET-查询 POST-添加 PUT-修改 DELETE-删除
* params:设置接收的参数,可以为表达式形式,
* username !username username=mcc username!=mcc
* 如处理参数有username,但没有password的请求 params={"username","!password"}
* headers:设置请求头信息
*/
//设置地址映射,即当请求地址为项目路径下的hello时,调用下面的方法
@RequestMapping(
value = "/hello",
method = RequestMethod.GET,
params = {"username"}
)
public String HelloGET() {
System.out.println("GET");
return "success";//设置视图名称
}
@RequestMapping(
value = "/hello",
method = RequestMethod.POST,
params = {"username","!password"}
)
public String HelloPOST() {
System.out.println("POST");
return "success";//设置视图名称
}
}
@RequestMapping("/*/ant")//表示请求路径ant上还要有一层任意其他目录
//@RequestMapping("/ab?/ant")//表示请求路径ant上还要有一层abx目录
//@RequestMapping("/**/ant")//表示请求路径ant上还要有一层或多层其他目录
public String ant() {
System.out.println("ANT");
return "success";//设置视图名称
}
springMVC 支持 REST 风格的参数传递。
浏览器地址栏中的地址:
之前:http://localhost:8080/springMVC/testREST?id=1&username=admin
现在:http://localhost:8080/springMVC/testREST/1/admin
(REST 风格)
实现方式:
(1)在@RequestMapping
的 value 属性中使用占位符{参数名}
确定参数的位置
(2)在方法的形参中使用@PathVariable("参数名")
注解,指明接收的参数名称
/**
* 浏览器地址栏中的地址:
* 之前:http://localhost:8080/springMVC/testREST?id=1&username=admin
* 现在:http://localhost:8080/springMVC/testREST/1/admin
*/
@RequestMapping("/testREST/{id}/{username}")
public String testREST(@PathVariable("id")Integer id, @PathVariable("username")String username) {
System.out.println("id="+id+", username="+username);
return "success";//设置视图名称
}
REST:即 Representational State Transfer。(资源)表现层状态转化,是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
使用 REST 风格进行增删改查操作时,需要使用 HTTP 协议里的四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET-获取资源,POST-新建资源,PUT-更新资源,DELETE-删除资源。
存在的问题:
form 表单只支持 GET 和 POST 请求,不支持其他两种请求。
解决的办法:
GET 请求用来处理查询操作,添加修改删除操作都使用 POST 请求完成,在发送请求时,添加一个参数,该参数用来区分本次 POST 请求用于处理的到底是何种操作。
Spring 的处理办法:
从 Spring3.0 开始,提供过滤器 HiddenHttpMethodFilter,该过滤器接收客户端(浏览器)发送的请求,判断请求方式是否为 POST,并且是否传递了参数_method
,若两个条件都满足,则将本次 POST 请求转换为 _method 传入的请求方式,若不满足条件,则继续使用 POST 请求。
注意:
PUT 与 DELETE 请求只能通过请求重定向实现页面的最终跳转,由于重定向不能访问 WEB-INF 目录下的文件,因此这里跳转到 WebContent 目录下的 success.jsp。
web.xml
<filter>
<filter-name>HiddenHttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
TestREST.java
package com.mcc.springMVC.rest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class TestREST {
@RequestMapping(value="/testREST/{id}",method=RequestMethod.GET)
public String testGET(@PathVariable("id")Integer id) {
System.out.println("test GET success, id="+id);
return "success";
}
@RequestMapping(value="/testREST",method=RequestMethod.POST)
public String testPOST() {
System.out.println("test POST success");
return "success";
}
@RequestMapping(value="/testREST",method=RequestMethod.PUT)
public String testPUT() {
System.out.println("test PUT success");
return "redirect:/success.jsp";
}
@RequestMapping(value="/testREST/{id}",method=RequestMethod.DELETE)
public String testDELETE(@PathVariable("id")Integer id) {
System.out.println("test DELETE success");
return "redirect:/success.jsp";
}
}
rest.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>REST-CURDtitle>
<base href=""/>
head>
<body>
<a href="/springMVC/testREST/1001">testGETa>
<form action="/springMVC/testREST" method="POST">
<input type="submit" value="testPOST"/>
form>
<form action="/springMVC/testREST" method="POST">
<input type="hidden" name="_method" value="PUT"/>
<input type="submit" value="testPUT"/>
form>
<form action="/springMVC/testREST/1001" method="POST">
<input type="hidden" name="_method" value="DELETE"/>
<input type="submit" value="testDELETE"/>
form>
body>
html>
在方法的形参位置,将形参名称与浏览器传入的参数名称设置相同。
浏览器的请求地址:http://localhost:8080/springMVC/param?id=1001&username=mcc
处理 param 请求的方法上:public String testParams(integer id, String username){}
此时,testParam 方法即可接收浏览器发送的参数。
当形参名称与浏览器发送的参数名称不同时,可以在形参前使用@RequestParam
注解,设置哪个形参接收哪个参数。
使用 name 接收 username:@RequestParam(value="username")String name
示例代码:
<body>
<form action="/springMVC/testParam" method="POST">
编号:<input type="text" name="id"/><br/>
用户名:<input type="text" name="username"/><br/>
兴趣:<input type="checkbox" name="hobby" value="java"/>java
<input type="checkbox" name="hobby" value="python"/>python
<input type="checkbox" name="hobby" value="C++"/>C++<br/>
<input type="submit"/>
form>
body>
@RequestMapping(value="/testParam",method=RequestMethod.POST)
public String testParams1(Integer id, String username, String[] hobby) {
System.out.println("id="+id+",username="+username+",hobby="+Arrays.toString(hobby));
return "success";
}
//用name接收username
@RequestMapping(value="/testParam",method=RequestMethod.GET)
public String testParams2(Integer id, @RequestParam(value="username")String name, String[] hobby) {
System.out.println("id="+id+",name="+name+",hobby="+Arrays.toString(hobby));
return "success";
}
@RequestParam(value,required,defaultValue)
@RequestMapping(value="/testParam",method=RequestMethod.POST)
public String testParams1(Integer id, String username, @RequestParam(value="hobby",required=false,defaultValue="java")String[] hobby) {
System.out.println("id="+id+",username="+username+",hobby="+Arrays.toString(hobby));
return "success";
}
@RequestHeader(value,required,defaultValue)
服务器不能直接在形参位置获取请求头信息,哪怕是将形参名称与请求头名称设置相同。
可以通过在形参前添加@RequestHeader
获取请求头信息。
@RequestMapping(value="/testParam",method=RequestMethod.POST)
public String testParams1(@RequestHeader(value="Accept")String Accept) {
System.out.println("Accept="+Accept);
return "success";
}
@CookieValue(value,required,defaultValue)
服务器不能直接在形参位置获取 Cookie 信息,哪怕是将形参名称与 Cookie 名称设置相同。可以通过在形参前添加@CookieValue
获取请求头信息。
@RequestMapping(value="/testParam",method=RequestMethod.POST)
public String testParams1(@CookieValue(value="JSESSIONID")String jsessionid) {
System.out.println("JSESSIONID="+jsessionid);
return "success";
}
在 springMVC 中,支持直接在方法的形参位置使用 Bean 对象接收浏览器传来的参数,springMVC 会自动将参数名与 Bean 对象的 get 方法进行匹配,若匹配成功则保存参数信息。
要求:
(1)浏览器传入的参数名称要与 Bean 对象的属性名称相同。
(2)springMVC 支持级联赋值,若 Bean 对象的属性包含其他对象(如 User 类有一个属性为 Address address),可以在浏览器端,将传入的参数名称改为address.属性名称
的形式,为 User 的 address 属性进行赋值。
User.java
package com.mcc.springMVC.pojoParam;
public class User {
private Integer id;
private String username;
private String gender;
private Address address;
//构造器、get()、set()、toString()省略
}
Address.java
package com.mcc.springMVC.pojoParam;
public class Address {
private String province;
private String city;
private String area;
//构造器、get()、set()、toString()省略
}
控制层方法
@Controller
public class TestPojo {
@RequestMapping(value="/testPojo",method=RequestMethod.POST)
public String testPojoInfo(User user) {
System.out.println(user);
//User [id=1001, username=admin, gender=01, address=Address [province=jilin, city=cc, area=cy]]
return "success";
}
}
表单
<body>
<form action="/springMVC/testPojo" method="POST">
编号:<input type="text" name="id"/><br/>
用户名:<input type="text" name="username"/><br/>
性别:<input type="radio" name="gender" value="01"/>男
<input type="radio" name="gender" value="02"/>女<br/>
省:<input type="text" name="address.province"/><br/>
市:<input type="text" name="address.city"/><br/>
区:<input type="text" name="address.area"/><br/>
<input type="submit"/>
form>
body>
如果需要使用 HttpServletRequest、HttpServletResponse 等 servlet 对象,可以在方法的形参部分传入对应的对象即可。
形参位置可以传入的原生 servlet 对象有:
<a href="/springMVC/testServletAPI?id=1001&username=mcc">servlet APIa>
@RequestMapping(value="/testServletAPI")
public void testServletAPI(HttpServletRequest req, HttpServletResponse resp) {
String id = req.getParameter("id");
String username = req.getParameter("username");
System.out.println("id="+id+" ,username="+username);//id=1001 ,username=mcc
}