SpringMVC(一)
SpringMVC的基本概念
-
三层架构
-
MVC模型
- Model(模型):通常就是指我们的数据模型,一般情况下用于封装数据。
- View(视图):通常指的就是我们的jsp或者html,一般用于展示数据。通常视图依据数据模型创建。
- Controller(控制器):是应用程序中处理用户交互的部分,一般用于处理程序逻辑。
-
SpringMVC :是一种基于 java 的实现 MVC 设计模型的请求驱动类型的轻量级 web 框架,属于Spring Framework 的后续产品,已经融合在Spring Web Flow中。spring框架提供了构建Web应用程序的全功能MVC模块。
-
它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无需实现任何接口,同时它还支持Restful 编程风格的请求。
-
优势:
- 清晰的角色划分
- 前端控制器(DispatcherServlet)
- 请求到处理器映射(HandlerMapping)
- 处理器适配器(HandlerAdapter)
- 视图解析器(ViewResolver)
- 处理器或页面控制器(Controller)
- 验证器(Validator)
- 命令对象(Command 请求参数绑定到的对象就叫命令对象)
- 表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)
- 分工明确,扩展灵活
- 由于命令对象就是一个POJO,无需继承框架特定API,可以使用命令对象直接作为业务对象。
- 和 spring 其他框架无缝集成,是其他 web 框架所不具备的。
- 可适配。通过 HandlerAdapter 可以支持任意的类作为处理器。
- 可定制性,HandlerMapping、ViewResolver 等能够非常简单的定制。
- 功能强大的数据验证、格式化、绑定机制。
- 利用spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
- 本地化、主题的解析的支持,使我们更容易的进行国际化和主题的切换。
- 强大的 JSP 框架,使 JSP 编写更加容易。
- Restful 风格的支持,简单的文件上传,约定大于配置的契约式编程支持,基于注解的零配置支持等等。
-
SpringMVC 和 Struts2 的优劣分析:
-
共同点:
- 他们都是表现层框架,都是基于 MVC 模型编写的。
- 他们的底层都离不开原始 ServletAPI。
- 他们处理请求的机制都是一个核心控制器。
-
区别:
- springMVC 的入口是 Servlet,而 Struts2 是 Filter。
- SpringMVC 是基于方法设计的,而 Struts2 是基于类,Struts2 每次执行都会创建一个动作类。所以SpringMVC(单例) 会稍微比 Struts2(多例) 快些。
- SpringMVC使用更加简洁,同时还支持JSR303(一套JavaBean 参数校验的标准,定义了很多常用的校验注解),处理 ajax 的请求更方便。
- struts2 的 OGNL 表达式使页面的开发效率相比 SpringMVC 更高些,但执行效率并没有比 JSTL 提升,尤其是 struts2 的表单标签,远没有 HTML 执行效率高。
SpringMVC的入门
-
需求:
- index.jsp (包含一个超链接标签)——> 发送请求 ——> 编写类、方法 ——> 转发到成功 jsp 页面
-
实现:
-
搭建开发环境
<servlet>
<servlet-name>dispatcherServlet</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>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context:component-scan base-package="com.ssm"></context:component-scan>
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:annotation-driven/>
-
编写入门程序
@Controller
public class HelloController {
@RequestMapping(path = "/hello")
public String sayHello(){
System.out.println("Hello SpringMVC");
return "success";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>入门程序</h3>
<a href="hello">入门程序</a>
</body>
</html>
-
@RequestMapping
:
- 如果出现在类上,表示请求URL的一级访问目录,不写则默认根目录,他的出现是为了使我们的url可以按照模块化管理。
- 如果出现在方法上,表示请求URL的二级访问目录。
- 属性:
value:用于指定请求的URL。他和path属性作用一样。
method:用于指定请求的方式。
params:用于指定限制请求参数的条件。支持简单表达式,要求参数的key和value必须和配置一模一样。
headers:用于指定限制请求消息头的条件。
请求参数的绑定
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/testParam")
public String testParam(String username,String password){
System.out.println("执行了……");
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
return "success";
}
}
<%--此处username和password必须与controller中方法参数名一样--%>
<body>
<a href="param/testParam?username=jinlu&password=123">请求参数的绑定</a>
</body>
</html>
- 把数据封装到Account类(JavaBean)中,类中存在对象引用、list、map集合等
@RequestMapping("saveAccount")
public String saveAccount(Account account){
System.out.println("执行……");
System.out.println(account);
return "success";
}
<%--把数据封装到Account类中,类中存在对象引用--%>
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
金额:<input type="text" name="money"/><br/>
用户:<input type="text" name="user.uname"/><br/>
年龄:<input type="text" name="user.age"/><br/>
<input type="submit" value="提交"/>
</form>
<%--把数据封装到Account类中,类中存在list和map集合--%>
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
金额:<input type="text" name="money"/><br/>
用户:<input type="text" name="list[0].uname"/><br/>
年龄:<input type="text" name="list[0].age"/><br/>
用户:<input type="text" name="map['one'].uname"/><br/>
年龄:<input type="text" name="map['one'].age"/><br/>
<input type="submit" value="提交"/>
</form>
-
自定义类型转换器
- 当实体类中含有如Date类型数据时,在jsp页面必须填写
yyyy/mm/dd
格式,如果写成yyyy-mm-dd
则会出错,无法转换日期类型,因为在jsp页面上的数据其实都是以 String 类型返回的。 - 自定义类型转换类及其方法:(必须实现接口Converter)
public class StringToDateConverter implements Converter<String,Date> {
@Nullable
@Override
public Date convert(String s) {
if (s == null){
throw new RuntimeException("请您传入数据");
}
DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
try {
return df.parse(s);
} catch (Exception e) {
throw new RuntimeException("数据类型转换出错");
}
}
}
配置自定义类型转换器:springmvc.xml
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.ssm.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"/>
-
获取Servlet 原生API
@RequestMapping("testServlet")
public String testServlet(HttpServletRequest request, HttpServletResponse response){
System.out.println("执行……");
System.out.println(request);
HttpSession session = request.getSession();
System.out.println(session);
ServletContext context = session.getServletContext();
System.out.println(context);
System.out.println(response);
return "success";
}
常用注解
-
@RequestParam
- 作用:把请求中指定名称的参数给控制器中的形参赋值
- 属性:
- value:请求参数中的名称
- required:请求参数中是否必须提供此参数,。默认为true,表示必须提供,如果不提供将报错。
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(name = "uname") String username){
System.out.println("执行了……");
System.out.println(username);
return "success";
}
<a href="anno/testRequestParam?uname=hah">requestParam注解</a>
-
@RequestBody
- 作用:用于获取请求体内容,直接使用得到是key=value&key=value……结构的数据。get请求方式不适用。
- 属性:
- required:是否必须有请求体,默认值为true,当取值为true时,get请求方式会报错。如果取值为false,get请求得到的是null。
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println("执行了……");
System.out.println(body);
return "success";
}
<form action="anno/testRequestBody" method="post">
用户姓名:<input type="text" name="username"><br/>
用户年龄:<input type="text" name="age"><br/>
<input type="submit" value="提交">
</form>
-
PathVariable
- 作用:用于绑定url中的占位符,例如:请求url中的 /delete/{id},这个 {id} 就是url的占位符。url 支持占位符是spring3.0 之后加入的。是springmvc 支持restful 风格 url 的一个重要标志。
- 属性:
- value:用于指定 url 中的占位符名名称。
- required:是否必须提供占位符。
@RequestMapping("/testPathVariable/{sid}")
public String testPathVariable(@PathVariable(name = "sid") String id){
System.out.println("执行了……");
System.out.println(id);
return "success";
}
<a href="anno/testPathVariable/10">PathVariable注解</a>
-
@RequestHeader
- 作用:用于获取请求消息头。
- 属性:
- value:提供消息头名称
- required:是否必须有此消息头。
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
System.out.println("执行了……");
System.out.println(header);
return "success";
}
-
@CookieValue
- 作用:用于把指定cookie 名称的值传入控制器方法参数。
- 属性:
- value:指定cookie的名称
- required:是否必须有此cookie
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){
System.out.println("执行了……");
System.out.println(cookieValue);
return "success";
}
-
@ModelAttribute
- 作用:
- 出现在方法上:表示当前方法会在控制器的方法前先执行。他可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
- 出现在参数上:获取指定数据的给参数赋值。
- 属性:
- value:用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key。
- 应用场景:
- 当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库原来的数据。
- 例如:我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据时肯定没有此字段的内容,一旦更新会把该字段的内容置为null,此时就可以使用此注解解决问题。
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("testModelAttribute执行了……");
System.out.println(user);
return "success";
}
@ModelAttribute
public User showUser(String uname){
System.out.println("showUser执行了……");
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setDate(new Date());
return user;
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("abc") User user){
System.out.println("testModelAttribute执行了……");
System.out.println(user);
return "success";
}
@ModelAttribute
public void showUser(String uname, Map<String,User> map){
System.out.println("showUser执行了……");
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setDate(new Date());
map.put("abc",user);
}
-
@SessionAttribute
- 作用:用于多次执行控制器方法间的参数共享。只能作用在类上。
- 属性:
- value:用于指定存入的属性名称。
- type:用于指定存入的数据类型。
@SessionAttributes(value = "msg")
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Model model){
System.out.println("testSessionAttributes执行了……");
model.addAttribute("msg","靳璐");
return "success";
}
@RequestMapping("/getSessionAttributes")
public String getSessionAttributes(ModelMap modelMap){
System.out.println("getSessionAttributes执行了……");
String str = (String) modelMap.get("msg");
System.out.println(str);
return "success";
}
@RequestMapping("/delSessionAttributes")
public String delSessionAttributes(SessionStatus status){
System.out.println("delSessionAttributes执行了……");
status.setComplete();
return "success";
}
success.xml
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>成功!!!</h3>
${requestScope.msg}
${sessionScope}
</body>
</html>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)