MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
基本步骤:
- 创建
maven
项目,并勾选出快速创建web环境项目选项(webapp)- 添加
pom
依赖- 编写
web.xml
文件- 编写
SpringMvc
相关xml
配置文件(如果是SSM还需要编写spring
的配置文件)- 创建并编写
Controller
相关代码- 配置
tomcat
(>7.0),并导入该项目
创建maven
项目,并勾选出快速创建web环境项目选项(webapp)
2. 添加pom
依赖
(此处应该有版本控制,不能想下面一样每个都写5.2.3… 像这样的版本号)
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.3.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.2.3.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.3.RELEASEversion>
dependency>
dependencies>
3. 编写web.xml
文件
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
4. 编写SpringMvc
相关xml
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter">bean>
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/">property>
<property name="suffix" value=".jsp">property>
bean>
<bean id="/hello" class="com.mashibing.controller.HelloController">bean>
beans>
** 5. 创建并编写Controller
相关代码**
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//创建模型和视图对象
ModelAndView mv = new ModelAndView();
//将需要的值传递到model中
mv.addObject("msg","helloSpringMVC");
//设置要跳转的视图,
mv.setViewName("hello");
return mv;
}
}
6. 配置tomcat
(>7.0),并导入该项目
标注在类上的注解:
核心注解 | 说明 |
---|---|
@Controller |
- |
@RestController |
- |
@RequestMapping |
设置整个控制层的请求前缀 |
@SessionAttributes |
此注解可以表示,当向request作用域设置数据的时候同时也要向session中保存一份,此注解有两个参数,一个value(表示将哪些值设置到session中),另外一个type(表示按照类型来设置数据,一般不用,因为有可能会将很多数据都设置到session中,导致session异常) |
标注在方法上的注解
核心注解 | 说明 |
---|---|
@RequestMapping |
指定 name属性,设置请求路径(根据method参数值,支持多种请求方式,默认都支持) |
@ResponseBody |
设置返回的方式,返回JSON 字符串。如果没有这个注解的话,就放回对应的视图 |
@GetMapping |
指定 name属性,设置请求路径,但只支持 Get 请求 |
@PostMapping |
和上述基本一直,但只支持 Post 请求 |
@DeleteMapping |
和上述基本一直,但只支持 Delete 请求 |
注意: 默认是不支持,put、delete
等请求的,这属于隐藏请求方式,需要自己手动开启(需要的话,自己可以百度自查,如何开启)
标注在参数上的注解
核心注解 | 说明 |
---|---|
@RequestParam |
指定请求的参数(一般通过请求url后的参数中获取,默认取相同名字的值)(建议指定相应的name) |
@RequestBody |
获取请求体中的值,(前端返回JSON数据格式,然后再通过转换成指定的对象格式) |
@PathVariable |
获取请求路径的值,默认取相同名字的值(建议指定相应的name) |
@RequestHeader |
获取请求头信息 |
@CookieValue |
获取cookie中的值 |
注意: 参数上指定了这些注解,默认是必传的参数,当然也可以设置参数为非必传(required=false)
说明:
我们在表单或者发送请求的时候,经常会遇到中文乱码的问题,那么如何解决乱码问题呢?
GET请求:在server.xml文件中,添加URIEncoding=“UTF-8”
POST请求:编写过滤器进行实现
解决方案:在web.xml
配置文件中添加编码过滤器
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc-servlet.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
HttpSession
、HttpServletRequest
、HttpServletResponse
等一系列API
(如果想更加深入理解Servlet 原生API的使用,可以自己查询相关文章)
ModelAndView
)直接上案例
@Controller
public class OutputController {
@RequestMapping("mv")
public ModelAndView mv(){
ModelAndView mv = new ModelAndView();
mv.setViewName("output"); // 设置视图页面
mv.addObject("msg","hello.modelAndView"); // 添加返回参数
return mv;
}
}
此功能主要是由 视图解析器
完成的功能
使用案例:(forward
、redirect
)
/**
* 当使用转发的时候可以添加前缀forward:index.jsp,此时是不会经过视图解析器的,所以要添加完整的名称
* forward:也可以由一个请求跳转到另外一个请求
*/
@RequestMapping("/forward01")
public String forward(){
System.out.println("1");
return "forward:/index.jsp";
}
/**
* redirect :重定向的路径
* 相当于 response.sendRedirect("index.jsp")
* 跟视图解析器无关
*/
@RequestMapping("redirect")
public String redirect(){
System.out.println("redirect");
return "redirect:/index.jsp";
}
当页面中包含静态资源的时候我们能够正确的获取到吗?
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
pageContext.setAttribute("ctx",request.getContextPath());
%>
Title
hello springmvc
在springmvc.xml
中添加相关配置
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
相关注解:@ResponseBody
、@RestController
@RequestBody
注意:一个请求只能有一个请求体
请求的参数,都是放在请求体中的。
与@RequestParam
不同。
springmvc
默认是不添加文件组件的(九大组件)
在springmvc.xml
的配置中,应该添加上:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8">property>
<property name="maxUploadSize" value="1024000">property>
bean>
文件上传:
@Controller
public class FileController {
@RequestMapping("/download")
public ResponseEntity<byte[]> download(HttpServletRequest request) throws Exception {
//获取要下载文件的路径及输入流对象
ServletContext servletContext = request.getServletContext();
String realPath = servletContext.getRealPath("/script/jquery-1.9.1.min.js");
FileInputStream fileInputStream = new FileInputStream(realPath);
byte[] bytes = new byte[fileInputStream.available()];
fileInputStream.read(bytes);
fileInputStream.close();
//将要下载文件内容返回
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Content-Disposition","attachment;filename=jquery-1.9.1.min.js");
return new ResponseEntity<byte[]>(bytes,httpHeaders,HttpStatus.OK);
}
}
文件下载:
@Controller
public class FileController {
@RequestMapping(value = "/testUpload", method = RequestMethod.POST)
public String testUpload(@RequestParam(value = "desc", required = false) String desc,
@RequestParam("file") MultipartFile multipartFile) throws IOException {
System.out.println("desc : " + desc);
System.out.println("OriginalFilename : " + multipartFile.getOriginalFilename());
multipartFile.transferTo(new File("D:\\file\\"+multipartFile.getOriginalFilename()));
return "success"; //增加成功页面: /views/success.jsp
}
}
核心步骤:
LocaleResolver
springmvc.xml
配置文件中,添加进入容器中ViewResolver
相关接口:视图解析器 ViewResolver
和 视图 View
使用案例
View
接口public class MyView implements View {
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("保存的对象是:"+model);
response.setContentType("text/html");
response.getWriter().write("欢迎加入马士兵教育");
}
/**
* 返回数据内容的类型
* @return
*/
public String getContentType() {
return "text/html";
}
}
ViewResolver
接口public class MyViewResolver implements ViewResolver, Ordered {
private int order = 0;
public View resolveViewName(String viewName, Locale locale) throws Exception {
//如果前缀是msb:开头的就进行解析
if (viewName.startsWith("msb:")){
System.out.println("msb:");
return new MyView();
}else{
//如果不是,则直接返回null
return null;
}
}
public int getOrder() {
return this.order;
}
public void setOrder(Integer order) {
this.order = order;
}
}
springmvc.xml
配置文件中添加进自定义视图解析器(在初始化视图解析器时,会根据对象类型获取Bean对象。因此只要将视图解析器,注入IOC容器中即可)
<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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.mashibing">context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/">property>
<property name="suffix" value=".jsp">property>
bean>
<bean class="com.mashibing.view.MyViewResolver">
<property name="order" value="1">property>
bean>
beans>
Converter
相关接口:
使用案例:
User.java
@Setter
@Getter
public class User {
private Integer id;
private String name;
private Integer age;
private String gender;
}
MyConverter.java
@Component
public class MyConverter implements Converter<String, User> {
public User convert(String source) {
User user = null;
String[] split = source.split("-");
if (source!=null && split.length==4){
user = new User();
user.setId(Integer.parseInt(split[0]));
user.setName(split[1]);
user.setAge(Integer.parseInt(split[2]));
user.setGender(split[3]);
}
return user;
}
}
springmvc.xml
的配置文件中添加装换器<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="myConverter">ref>
set>
property>
bean>
适用场景:
@DateTimeFormat
有时候我们经常需要在页面添加日期等相关信息,此时需要制定日期格式化转换器,此操作非常简单:只需要在单独的属性上添加@DateTimeFormat
注解即可,制定对应的格式
一般情况下我们会在前端页面实现数据的校验,但是大家需要注意的是前端校验会存在数据的不安全问题,因此一般情况下我们都会使用前端校验+后端校验的方式,这样的话既能够满足用户的体验度,同时也能保证数据的安全,下面来说一下在springmvc中如何进行后端数据校验。
JSR303是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中 。JSR 303 (Java Specification Requests意思是Java 规范提案)通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证。
JSR303:
Hibernate Validator 扩展注解:
使用案例
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-validatorartifactId>
<version>5.1.0.Finalversion>
dependency>
User.java
@Data
public class User {
private Integer id;
@NotNull
@Length(min = 5,max = 10)
private String name;
private Integer age;
private String gender;
@Past
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
@Email
private String email;
}
DataValidateController.java
@Controller
public class DataValidateController {
@RequestMapping("/dataValidate")
public String validate(@Valid User user, BindingResult bindingResult) {
System.out.println(user);
if (bindingResult.hasErrors()) {
System.out.println("验证失败");
return "redirect:/index.jsp";
} else {
System.out.println("验证成功");
return "hello";
}
}
}
form.jsp
<%--
Created by IntelliJ IDEA.
User: root
Date: 2020/3/12
Time: 15:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$