SpringMVC简单总结
- 一、SpringMVC需要的maven依赖?
- 二、SpringMVC需要的配置文件
- 1.在Web.xml下的文件
- 2.resources目录下的springMVC.xml配置
- 3.控制器的用法
- 1、创建控制器
- 2.地址为index或outdex,get方法,参数username=1,没有password的请求进入到index页面
- 3.地址为.../testPath/id的方法进入,此处id是传的参数,此处配合前端一般是a标签传参,比如需要删除一个id为2的学生信息
- 4.地址为testPara,参数为username和password,此处一般为form表单提交,后端获取表单信息,以下两种方法都可以
- 5.当form表单有别名时,required表示没有参数也能通过,defaultvalue表示默认值
- 6.当一个表单有很多条数据时,我们可以把他们封装成一个类传参,此处userInfo和user数据一样
- 7.session的使用,用原生的方法比较简单
- 8.Requst可以用原生的方法,但是在SpringMVC里面提供了几个更好的方法
- 9.向另一个网页发送json数据,需要json的maven依赖
- 10.Ajax发送json数据,需要vue.js包和axios.js包
- 11.在SpringMVC中,我们一般get方式请求进行查询操作,post方式请求进行增加操作,put方式请求进行更新操作,delete请求方式进行删除操作
- 12.重定向和请求转发
- 13.我有一个数据集,如何在网页上全部显示,用到了th:each将list集循环显示
- 14.RequestBody和RequestEntity,一个是请求体,一个是请求体和请求头都有
- 15.文件下载和上传
- 16.过滤器
- 17.异常处理注释法
- 未完成目标
一、SpringMVC需要的maven依赖?
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demo</name>
<packaging>war</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>5.7.0</junit.version>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 -->
<!-- thymeleaf2 layout1-->
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
</properties>
<dependencies>
<!--启用不严格检查html-->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version> </dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.uuid/java-uuid-generator -->
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</build>
</project>
二、SpringMVC需要的配置文件
1.在Web.xml下的文件
代码如下(示例):
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 配置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>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 通过初始化参数指定SpringMVC配置文件的位置和名称 -->
<init-param> <!-- contextConfigLocation为固定值 -->
<param-name>contextConfigLocation</param-name>
<!-- 使用classpath:表示从类路径查找配置文件,例如maven工程中的 src/main/resources -->
!!! 这里的springMVC.xml文件可以新建在resources目录下,我的工程文件名为springMVC.xml,可以另取
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!--作为框架的核心组件,在启动过程中有大量的初始化操作要做 而这些操作放在第一次请求时才执行会严重影响访问速度 因此需要通过此标签将启动控制DispatcherServlet的初始化时间提前到服务器启动时 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<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>
</web-app>
2.resources目录下的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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 1、配置注解驱动:识别注解标志
spring提供的注解比如@Component @Service @Controller @Repository
在SpringMVC中能够将带有该注解的类扫描给Spring容器进行管理
但是要想SpringMVC实现更加完成的功能,SpringMVC又封装自身的注解比如@RequestMapping @GetMapping .....
-->
<!-- 2、配置包扫描
将带有@Component @Service @Controller @Repository这些注解的类交给Spring容器进行管理
base-package:基于哪个包进行扫描,扫描根包所有子包都会被扫描
-->
!!!需要配置扫描器的包位置
<context:component-scan base-package="com.example.demo"></context:component-scan>
<!-- 3、内部资源视图解析器
最终实现把页面的正确路径进行拼接
/WEB-INF/jsp/ login(返回的视图名)
-->
<!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
!!!我的WEB_INF目录下新建了一个pages目录,我把网页放在pages目录下
<property name="prefix" value="/WEB-INF/pages/"/>
<!-- 视图后缀 -->
!!!想要jsp可以改为.jsp
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
</bean>
</property>
</bean>
</property> </bean>
<!--处理静态资源,例如html、js、css、jpg 若只设置该标签,则只能访问静态资源,其他请求则无法访问 此时必须设置<mvc:annotation-driven/>解决问题 -->
<mvc:default-servlet-handler/>
<!-- 开启mvc注解驱动 -->
<mvc:annotation-driven> <mvc:message-converters>
<!-- 处理响应中文内容乱码 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8" />
<property name="supportedMediaTypes">
<list>
<value>text/html</value>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
!!!下面是过滤器配置
第一种方法,对所有网页进行过滤
<!-- <mvc:interceptors>
<bean class="com.example.demo.interceptor"></bean>
</mvc:interceptors>-->
第二种方法,对除了/login的网页进行过滤
<!--<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<ref bean="interceptor"></ref>
</mvc:interceptor>
</mvc:interceptors>-->
多个过滤器一起设置,preHandle是顺序执行,也就是先interceptor再interceptor2
postHandle和afterCompletion是逆序执行, 也就是先interceptor2再interceptor
<mvc:interceptors>
<ref bean="interceptor"></ref>
<ref bean="interceptor2"></ref>
</mvc:interceptors>
异常处理,当出现ArithmeticException跳转error页面
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--properties的键表示处理器方法执行过程中出现的异常 properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面 -->
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!--exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中进行共享 -->
ex是键,异常信息是值,在html页面可以用<p th:text="${ex}"></P>显示
<property name="exceptionAttribute" value="ex"></property> </bean>
</beans>
3.控制器的用法
1、创建控制器
@Controller
public class controller {
@RequestMapping("/login")
public String login()
{
return "login";
}
}
2.地址为index或outdex,get方法,参数username=1,没有password的请求进入到index页面
@RequestMapping(
value ={ "/index","outdex"},method = {RequestMethod.GET},
params = {"username=1","!password"}
public String index()
{
return "index";
}
)
3.地址为…/testPath/id的方法进入,此处id是传的参数,此处配合前端一般是a标签传参,比如需要删除一个id为2的学生信息
前端代码为
<a th:href="@{/testPath/1}">删除id为1的学生信息</a>
@RequestMapping("/testPath/{id}")
public String TestPath(@PathVariable("id") Integer id)
{
System.out.println(id);
return "index";
}
4.地址为testPara,参数为username和password,此处一般为form表单提交,后端获取表单信息,以下两种方法都可以
<a th:href="@{/testPara(username='king',password=12345)}">测试传参</a>
<form th:action="@{/testPara}" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>
@RequestMapping("/testPara")
public String test1(String username,String password)
{
System.out.println("用户名: "+username);
System.out.println("密码: "+password);
return "index";
}
5.当form表单有别名时,required表示没有参数也能通过,defaultvalue表示默认值
<a th:href="@{/testPara2(user_name='king',password=12345)}">测试下划线传参</a>
@RequestMapping("/testPara2")
public String test2(@RequestParam(value = "user_name",required = false,defaultValue = "hhhh") String username, String password)
{
System.out.println("用户名: "+username);
System.out.println("密码: "+password);
return "index";
}
6.当一个表单有很多条数据时,我们可以把他们封装成一个类传参,此处userInfo和user数据一样
<form th:action="@{/testPojo}" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" value="男">男<input type="radio" name="sex" value="女">女<br>
年龄:<input type="text" name="age"><br>
邮箱:<input type="text" name="email"><br>
<input type="submit">
</form>
@RequestMapping("/testPojo")
public String testPojo(User user,User userInfo)
{
System.out.println(userInfo.getPassword());
System.out.println(user.toString());
System.out.println(user.getSex());
System.out.println(user.getAge());
System.out.println(user.getEmail());
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return "index";
}
7.session的使用,用原生的方法比较简单
<a th:href="@{/testSession}">testSession的方法</a>
数据回显
<p th:text="testSession"></p>
@RequestMapping("/testSession")
public String testSession(HttpSession session)
{
session.setAttribute("testSession","hello testSession");
return "index";
}
8.Requst可以用原生的方法,但是在SpringMVC里面提供了几个更好的方法
一、ModelAndView
<a th:href="@{/testRequest}">testRequest的方法</a>
数据回显
<p th:text="testRequest"></p>
@RequestMapping("/testRequest")
public ModelAndView testRequest(ModelAndView ModelAndView)
{
ModelAndView mav = new ModelAndView();
mav.addObject("testRequest","testRequest");
mav.setViewName("index");
return mav;
}
二、model
@RequestMapping("/testRequest")
public ModelAndView testRequest(Model Model)
{
model.addAttribute("testRequest",testRequest);
return index;
}
9.向另一个网页发送json数据,需要json的maven依赖
@RequestMapping("/testJson")
@ResponseBody
public User testJson()
{
User user = new User();
user.setUsername("testUsername");
user.setPassword("testPassword");
user.setAge(12);
user.setEmail("testEmail");
user.setSex("testSex");
return user;
}
10.Ajax发送json数据,需要vue.js包和axios.js包
<div id="app">
<a th:href="@{/testAjax}" @click="testAjax">testAjax</a>
<br>
</div>
<script type="text/javascript">
var vue = new Vue({
el:"#app",
methods:{
testAjax:function (event) {
axios(
{
method:"post",
url:event.target.href,
params:{
username:"admin",
password:"123456"
}
}
).then(function (response)
{
alert(response.data);
}
);
event.preventDefault();
}
}
});
</script>
@RequestMapping("/testAjax")
@ResponseBody
public String testAjax(String username, String password)
{
System.out.println("username:"+username+",password:"+password);
return "hello,ajax";
}
11.在SpringMVC中,我们一般get方式请求进行查询操作,post方式请求进行增加操作,put方式请求进行更新操作,delete请求方式进行删除操作
一、get
@RequestMapping(value = {"/testget"},method = {RequestMethod.GET})
public String testget(String username,String password)
{
System.out.println("查询操作成功"+" -用户名"+username+" -密码"+password);
return "success";
}
二、post
@RequestMapping(value = {"/testpost"},method = {RequestMethod.POST})
public String testpost(String username,String password)
{
System.out.println("增加操作成功"+" -用户名"+username+" -密码"+password);
return "success";
}
三、put
<form th:action="@{/testput}" method="post">
<input type="hidden" name="_method" value="put">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="put方法更新操作">
</form>
@RequestMapping(value = {"/testput"},method = {RequestMethod.PUT})
public String testput(String username,String password)
{
System.out.println("更新操作成功"+" -用户名"+username+" -密码"+password);
return "success";
}
四、******delete最复杂
<table id="dataTable" border="1" cellspacing="0" cellpadding="0" style="text-align: center;">
<tr>
<th colspan="5">Employee Info</th>
</tr>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>options</th>
</tr>
<tr>
<td>1号数据</td>
<td>2号数据</td>
<td>3号数据</td>
<td>4号数据</td>
<td>
<a @click="deleteEmployee" th:href="@{'/testVue/'+${'154'}}">delete</a>
<a th:href="@{'/employee/'+${1}}">update</a>
</td>
</tr>
</table>
此时,我们的a标签只是一个普通的get请求,那么我们如何让他变为delete方法的请求呢
<form id="deleteForm" method="post">
<input type="hidden" name="_method" value="delete">
</form>
<script type="text/javascript">
var vue = new Vue({
el:"#dataTable",
methods:{
deleteEmployee:function (event) {
//根据id获取表单元素
var deleteForm = document.getElementById("deleteForm");
//将触发点击事件的超链接的href属性赋值给表单的action
deleteForm.action = event.target.href;
//提交表单
deleteForm.submit();
//取消超链接的默认行为
event.preventDefault();
}
}
});
</script>
我们先用el找到dataTable元素,然后用@Click找到a标签,将a标签的请求方式和请求改为deleteForm类型的请求,再取消默认行为,就可以得到了,同理需要put请求的时候也可以这样修改
@RequestMapping(value = {"/testVue/{id}"},method = {RequestMethod.DELETE})
public String testVue(@PathVariable("id") String id)
{
System.out.println("testVue删除成功"+" -值为"+id);
return "success";
}
12.重定向和请求转发
@RequestMapping("/testForward")
public String testForward()
{
return "forward:/testHello";
}
@RequestMapping("/testRedirect")
public String testRedirect()
{
return "redirect:/testHello";
}
13.我有一个数据集,如何在网页上全部显示,用到了th:each将list集循环显示
<table border="1" cellpadding="0" cellspacing="0" style="text-align: center;" id="dataTable">
<tr>
<th colspan="5">Employee Info</th>
</tr>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>options(<a th:href="@{/toAdd}">add</a>)</th>
</tr>
<tr th:each="employee : ${employeeList}">
<td th:text="${employee.id}"></td>
<td th:text="${employee.lastName}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.gender}"></td>
<td>
<a class="deleteA" @click="deleteEmployee" th:href="@{'/testVue/'+${employee.id}}">delete</a>
<a th:href="@{'/employee/'+${employee.id}}">update</a>
</td>
</tr>
</table>
14.RequestBody和RequestEntity,一个是请求体,一个是请求体和请求头都有
<form th:action="@{/RequestBody}" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="测试RequestBody">
</form>
<form th:action="@{/RequestEntity}" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="测试RequestEntity">
</form>
@RequestMapping("/RequestBody")
public String RequestBody(@RequestBody String RequestBody)
{
System.out.println(RequestBody);
return "success";
}
@RequestMapping("/RequestEntity")
public String RequestEntity(RequestEntity<String> RequestEntity)
{
System.out.println("请求头"+RequestEntity.getHeaders());
System.out.println("请求体"+RequestEntity.getBody());
return "success";
}
15.文件下载和上传
一.文件下载,除了有关文件名的需要改动,其他都不需要
<a th:href="@{/testDown}">下载1.jpg</a><br>
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
我的webapps下面有一个static包,里面有1.png图片
String realPath = servletContext.getRealPath("/static/1.png");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=1.png");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
//关闭输入流
is.close();
return responseEntity;
}
·二.文件上传,基本不需要改动
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
头像:<input type="file" name="photo"><br>
<input type="submit" value="上传">
</form>
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException
{
//获取上传的文件的文件名
String fileName = photo.getOriginalFilename();
//处理文件重名问题
hzName是文件的后缀名
String hzName = fileName.substring(fileName.lastIndexOf("."));
UUID是随机生成的一个很少重复的字符串,如djawoddhqwou312312ed
fileName = UUID.randomUUID().toString() + hzName;
//获取服务器中photo目录的路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath); if(!file.exists()){ file.mkdir();
}
String finalPath = photoPath + File.separator + fileName;
//实现上传功能
photo.transferTo(new File(finalPath));
return "success";
}
16.过滤器
在SpringMVC.xml配置,详情可见SpringMVC配置里面的注释
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class interceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle方法执行");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle方法执行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion方法执行");
}
}
17.异常处理注释法
也有xml配置法,也在SpringMVC.xml里注释的有
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(ArithmeticException.class)
public String testException(Exception ex, Model model)
{
System.out.println("执行到这里来");
model.addAttribute("ex",ex);
return "error";
}
}