SpringMVC 就是代替 三层结构中表示层后台的 servlet ,参数传递 REST风格和普通风格 pojo作为handler 方法参数接收前台信息
目录
〇、文件配置&测试
SpringMVC 可以代替servlet功能,可以更简单的通过使用springMVC 实现控制器功能
servlet通过 标签 在 web.xml 中的<servlet-mapping> <servlet> 拦截前台请求,转发到后台,springMVC通过在 web.xml 中(Alt+/)配置 DispatcherServlet标签,使用 / 拦截所有请求到 springMVC的配置文件中代替servlet。对应拦截的方式也有点“.”开头只检查后缀:
web.xml 配置如下:
<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">
<welcome-file-list>
<welcome-file>index.html</welcome-file>.........
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value> //该配置文件在src路径下
</init-param>
<load-on-startup>1</load-on-startup>
</servlet><!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern> //拦截所有的请求
</servlet-mapping></web-app>
web.xml 文件将请求拦截后转发到SpringMVC的配置文件,在该配置文件中完成前/后缀的配置,
<!-- 配置扫描包 -->
<context:component-scan base-package="priv.mvc.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>
(SpringMVC.xml 文件可以不在src目录下,可以重命名为 springDispatcherServlet-servlet.xml 文件 后在放在WEB-INF文件夹中).上述项目实现功能很简单,既简单的请求转发功能:
(index.jsp-----请求转发到----->sucess.jsp(配置文件的/views/前缀是一个文件夹,最终路径为 http://127.0.0.1:8080/SpringMVC_001/welcome)) 。 SpringMVC_Handler代码如下:
@Controller
public class SpringMVC_Handler {
@RequestMapping("welcome") //拦截到的信息welcome时执行此方法
public String welcome() {
return "sucess" ; //返回的参数 前/后缀 已在springMVC.xml文件中配置完成
}
}
一、 SpringMVC基本使用
将上述的测试用的index.xml 与 控制器(handler)代码进行更改。
<body>
<a href="welcome">MVC - welcome-get</a>
<br><br><br>
<form action="handler/transer" method="post">
<input type="submit" value="post_submit">
</form>
<br><br><br>
<form action="judge/handler" method="post">
姓名 : <input name="name"><br>
年龄 : <input name="age"><br>
地址: <input name="address">
<input type="submit" value="judge_submit">
</form>
</body>
</html>
显示效果如下:
handler代码如下:
@Controller
public class SpringMVC_Handler {
@RequestMapping("welcome")
public String welcome() {
return "sucess" ;
}
@RequestMapping(value="handler/transer" , method=RequestMethod.POST)
public String postHandler() {
return "sucess";
}
@RequestMapping(value="judge/handler" ,
method=RequestMethod.POST, params= {"name=zs","age!=23","!address"})
public String judgeHandler() {
return "sucess";
}
RequestMapping中的三个参数,value为index中对应的请求,method规定了请求方法,params可以判断请求中带的参数 必须要有name(必须为zs)和age(不能为23),且不能有名为 address 的参数。 否则报错信息:
Parameter conditions "name=zs, age!=23, !address" not met for actual request parameters: name={zs1}, age={23}, address={hf}
RequestMapping中的 参数支持ant风格:
* 代表handler接受请求的参数中包含任意字符 **代表handler接受请求的参数中包含任意目录 ?代表handler接受请求的参数中包含一个任意形式的字符
handler中的方法如下:(实际测试2或者3 时要注释掉其他两个方法)
@RequestMapping(value="*/handler" )
public String antHandler_01() {
return "sucess";
}
@RequestMapping(value="ant/**/handler" )
public String antHandler_02() {
return "sucess";
}
@RequestMapping(value="ant?/handler" )
public String antHandler_03() {
return "sucess";
}
index.xml中的 请求如下:
<br> <a href="ant/handler">ant_1个 *</a> <br>
<br>
<a href="ant/abc/handler">ant_2个 *</a><br>
<br>
<a href="antX/handler">ant_1个 ? </a>
<br>
二、参数获取
1.RESTful 风格实现 传递参数值
(资源)表现层状态转化风格编程 :普通浏览器仅支持解析 get/post 方法,不支持解析 put/delete 请求。在中间经过过滤器后添加新的请求方式实现支持解析。 springMVC支持对特定的请求进行过滤配置(HiddenHttpMethodFilter)。约定隐藏域,name为“_method”,value可以为put/delete 并且请求方式必须为post(不能为get),即可将post转化为put/delete 请求。
首先在web.xml文件中配置过滤器(filter),HiddenHttpMethodFilter 类处理put/delete 等请求
<!-- http方法 (主要针对 put/delete)配置过滤器 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter><filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- 拦截全部请求 -->
</filter-mapping>
之后在index.jsp(请求端)中的post请求中进行隐藏域等配置
<br> ======REST======<br>
<form action="handler/testRest/1234" method="post">
<input type="submit" value="rest_add">
</form>
<br>
<form action="handler/testRest_delete/2234" method="post">
<input type="hidden" name="_method" value="DELETE" />
<input type="submit" value="rest_delete">
</form>
<br><!-- 更新 rest 风格 -->
<input type="hidden" name="_method" value="UPDATE"/>
<input type="submit" value="rest_update">
</form>
<br> <!-- 查询 rest 风格(get方式)--> <br>
<form action="handler/testRest/4024" method="get">
<input type="hidden" name="_method" value="QUERY"/>
<input type="submit" value="rest_query">
</form>
testRest 方法出现两次,要想在控制器(handler)中区分,需要在该方法的注解中添加method=RequestMtehod.XXX(GET/PUT/DELETE/...) 。 handler/testRest/1234 中的 /1234 是参数传入到控制器(handler)中。 隐藏域中的 value="DELETE" 值必须都大写。
最后在控制器(handler)中处理请求,配置如下(PathVariable接受该参数值传入函数参数):
@RequestMapping("handler/testRest/{id}") //接受请求端发来的参数
public String testRest(@PathVariable("id") Integer id) {
//PathVariable接受该参数值传入函数参数
System.out.println("id_post_add "+id);
return "sucess" ;
}
@RequestMapping("handler/testRest_delete/{id}")
public String testRest_delete(@PathVariable("id") Integer id) {
System.out.println(" _postToDel_delete "+id);
return "sucess" ;
}
//handler/testRest_update --- REST 风格更新
@RequestMapping("handler/testRest_update/{id}")
public String testRest_update(@PathVariable("id") Integer id) {
System.out.println(" _postToUPDATE_id "+id);
return "sucess";
}
//handler/rest_query/0004 --- REST 风格查询 方法名同增加方式,使用method= RequestMethod.GET区分
@RequestMapping(value="handler/testRest/{id}" ,method= RequestMethod.GET)
public String testRest_get(@PathVariable("id") Integer id) {
System.out.println("rest_query :" +id);
return "sucess";
}
如果报错 JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS 在目标jsp(sucess)的头部添加 isErrorPage="true" ,如下:
2.普通方法传 递参数值
不适用rest风格直接使用普通的方法传值参数值到控制器后台:
前台JSP文件表单如下:
<!-- 普通方式向后台传参数值--> <br>
<form action="handler/transPara" method="get">
name : <input name="uname" /> <br>
age : <input name="uage" /> <br>
<input type="submit" value="transPara">
</form>
对应的控制器(handler)代码如下(age为非必填项,如果空值则默认为 100 ):
//handler/transPara ---普通方式传递参数 代替 request.getParameter("uname")
@RequestMapping(value="handler/transPara",method= RequestMethod.GET)
public String transParaGet(@RequestParam("uname") String uname,@RequestParam(value="uage",required=false ,defaultValue="100") String uage) {
System.out.println("transPara-- : "+uname+"---"+uage);
return "sucess";
}
@RequestParam(value="uage",required=false ,defaultValue="100") String uage 为非必填值
三、Java对象作为参数传递
与servlet不同,SpringMVC 的控制器(handler)支持Java对象结束请求参数
首先创建实体类,之后在前台的表单中创建对应实体类的表单name,如果实体类的数据是Java类则前台表单的name属性值为级联形式(类名.属性名)。控制器 直接使用该实体类对象作为方法的参数传入即可。
前端form表单如下:
<!-- 控制器用实体类接受传参 --> <br>控制器用实体类接受传参 <br>
<form action="handler/pojo" method="post">
id: <input name="id" /> <br>
name : <input name="name" /> <br>
provinceAdress : <input name="address.provinceAddress" /> <br>
cityAdress : <input name="address.cityAddress" /> <br>
<input type="submit" value="pojoTransfer">
</form>
对应的实体类Person 中有Address类型对象 属性(包含cityAddress & provinceAddress属性)。使用“.”作为级联属性方式。 配置handler控制器的方法直接使用Person类作为参数,代码如下:
//handler/pojo"
@RequestMapping(value="handler/pojo")
public String pojoAccept( Person person) {
String infor = person.toString();
//toString() 方法为自定义方法 打印该类中的各个属性
System.out.println("infor: "+infor);
return "sucess";
}
springMVC获取JSP 信息 如果 打印后出现乱码,可以在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" id="WebApp_ID" version="3.1">
<!--配置springMVC的编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
。。。。。。。
该过滤器的配置必须在最前面!!!
总结
SpringMVC 处理各种参数(包括jsessionid cookieid):
前端发请求--->控制器(handler)通过在相应的方法上添加注解@RequestMapping("XXX") 再通过使用其他对应的注解(@RequestParam || REST 风格 @PathVariable)获取对应的请求参数将其保存到方法参数中 。该方法的返回值通过在web.xml中配置前后缀就是后台的地址。后期可以使用 实体类作为请求参数。