SpringMVC基础-02
SpringMVC基础-02
1.处理乱码问题
- web.xml中配置CharacterEncodingFilter。
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Archetype Created Web Application</display-name>
<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-01.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 解决乱码问题 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
-
解决json乱码问题。即使web.xml配置了CharacterEncodingFilter,但如果返回的是json数据依然会出现乱码问题。
- 解决方式一。请求中设置produces = "application/json;charset=utf-8",定义输出格式。
@Controller @RequestMapping("/hello") public class HelloController { /** * 解决json乱码问题 * @return */ @ResponseBody @GetMapping(value = "/h1", produces = "application/json;charset=utf-8") public String h1() { User user = new User(2, "张三", 10); ObjectMapper objectMapper = new ObjectMapper(); String s = null; try { s = objectMapper.writeValueAsString(user); } catch (JsonProcessingException e) { e.printStackTrace(); } return s; } }
- 解决方式二。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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 解决json的乱码问题 --> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="failOnEmptyBeans" value="false"/> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> </beans>
-
Tomcat乱码问题解决。
- 修改apache-tomcat-9.0.50\conf\server.xml中70行的配置。
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
2.json
- 导入依赖。有两种json工具类,任选其一即可。
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
- jackson的使用。先new ObjectMapper();,然后调用writeValueAsString()方法
@Controller
@RequestMapping("/hello")
public class HelloController {
@ResponseBody
@GetMapping("/h1")
public String h1() {
User user = new User(1, "张三", 10);
ObjectMapper objectMapper = new ObjectMapper();
String s = null;
try {
s = objectMapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return s;
}
/**
* 直接将日期格式化为Json,会输出一个时间戳 1627822830320
* @return
* @throws JsonProcessingException
*/
@ResponseBody
@GetMapping("/h2")
public String h2() throws JsonProcessingException {
Date date = new Date();
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(date);
}
/**
* 将日期格式化后输出。
* @return
* @throws JsonProcessingException
*/
@ResponseBody
@GetMapping(value = "/h3")
public String h4() throws JsonProcessingException {
Date date = new Date();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
mapper.setDateFormat(format);
return mapper.writeValueAsString(date);
}
}
3.fastjson的使用。JSON.toJSONString(),将对象解析为json字符串;JSON.parseObject(),json字符串解析为对象。
@Controller
@RequestMapping("/hello")
public class HelloController {
@ResponseBody
@GetMapping("/h1")
public String h1() throws JsonProcessingException {
User user = new User(2, "张三", 10);
// User解析为Json字符串
String s = JSON.toJSONString(user);
// Json字符串解析为User对象
User user1 = JSON.parseObject(s, User.class);
return s + user1;
}
}
3.SSM整合
- 导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<!-- 低版本servlet-api -->
<!--<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>-->
<!-- 高版本的servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
</dependencies>
-
dao配置文件。database.properties、spring-dao.xml、mybatis.xml、mapper.xml。
- database.properties,MySQL8.0之后,需要设置时区配置。
driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=Asia/Shanghai name=root password=123456
- spring-dao.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath:database.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${driverClassName}"/> <property name="jdbcUrl" value="${url}"/> <property name="user" value="${name}"/> <property name="password" value="${password}"/> <property name="maxPoolSize" value="30"/> <property name="minPoolSize" value="10"/> <property name="autoCommitOnClose" value="false"/> <!-- 获取连接超时时间 --> <property name="checkoutTimeout" value="10000"/> <!-- 连接失败尝试次数 --> <property name="acquireRetryAttempts" value="2"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- mybatis配置文件,web项目中value必须配置为classpath:,否则无法找到路径。 --> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!-- mapper配置文件 --> <property name="mapperLocations" value="classpath*:com/my/dao/*.xml"/> <!-- 别名包的配置 --> <property name="typeAliasesPackage" value="com.my.pojo"/> </bean> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!-- 将dao通过注解注入spring容器 --> <property name="basePackage" value="com.my.dao"/> </bean> </beans>
- mabatis.xml配置。别名也可以在spring-dao.xml中进行配置。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <package name="com.my.dao.User"/> </typeAliases> </configuration>
- mapper.xml配置。需要和com.my.dao.UserDao的路径名称保持一致。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.my.dao.UserDao"> <select id="getAll" resultType="com.my.pojo.User"> select * from tb_user </select> </mapper>
-
spring-server层配置。
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.my.service"/>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>
- spring-controller配置。
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 扫描@Controller注解 -->
<context:component-scan base-package="com.my.controller"/>
<!-- 注解驱动。可以使用@RequestMapping、@GetMapping定义url。 -->
<mvc:annotation-driven/>
<!-- 静态资源过滤 -->
<mvc:default-servlet-handler/>
<!-- 视图解析 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- applicationContext.xml,将spring-dao.xml、spring-server.xml、spring-controller.xml到导入到applicationContext.xml中,在Tomcat启动时加载。
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:spring-controller.xml"/>
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
</beans>
- web.xml配置。
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 将Spring容器存在于Tomcat -->
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- session过期时间 -->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
4.拦截器。
-
拦截器的概念。
- servlet中有过滤器(Filter)和监听器(EventListener,监听域对象中数据的变化),其中过滤器在url-pattern配置了/*之后,可以对所有要访问的资源进行拦截。
- 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才可以使用,同时拦截器类似于Servlet中的过滤器。
- 拦截器只拦截访问控制器的方法,如果访问的是jsp/html/css/image/js是不会进行拦截的。
-
拦截器的实现。
- 定义一个拦截器。
public class MyInterceptor implements HandlerInterceptor { /** * * @param request * @param response * @param handler * @return 返回true,执行下一个拦截器;返回false,拦截。 * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("方式执行前====="); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("方式执行后====="); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("=====方式执行后====="); } }
- 配置拦截器。
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- /** 拦截这个请求下的所有的请求 --> <mvc:mapping path="/**"/> <bean class="com.my.interceptor.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors> </beans>
5.文件上传和下载
-
文件上传和下载的配置。
- 需要导入的依赖。
<!-- 文件上传 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
- 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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 文件上传和下载 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 请求的编码格式,必须和jsp的pageEncoding一致,以便正确读取表单内容,默认为ISO-8859-1 --> <property name="defaultEncoding" value="UTF-8"/> <!-- 上传文件大小限制,单位为字节,10485760=10M --> <property name="maxUploadSize" value="10485760"/> <property name="maxInMemorySize" value="40960"/> </bean> </beans>
-
文件上传和下载的代码实现。
- 文件上传。
@Controller public class FileUploadController { /** * 自定义文件传出。 * 会将上传的名为file的文件封装为CommonsMultipartFile。 * @param file * @param request * @return */ @PostMapping("/upload") public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException { String uploadFileName = file.getOriginalFilename(); if ("".equals(uploadFileName)) { return "redirect:/index.jsp"; } System.out.println("上传文件名: " + uploadFileName); String s = "E:\\Temp" + File.separator + "update"; File path = new File(s); if (!path.exists()) { path.mkdir(); } System.out.println("文件保存路径: " + path); InputStream inputStream = file.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream(new File(path, uploadFileName)); int len = 0; byte[] buffer = new byte[1024]; while ((len = inputStream.read(buffer)) != -1) { fileOutputStream.write(buffer); fileOutputStream.flush(); } inputStream.close(); fileOutputStream.close(); return "redirect:/index.jsp"; } /** * 使用CommonsMultipartFile中的方法直接完成文件传输。 * @param file * @param request * @return * @throws IOException */ @PostMapping("/upload") public String upload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException { String s = "E:\\Temp" + File.separator + "update2"; File path = new File(s); if (!path.exists()) { path.mkdir(); } System.out.println("文件保存路径: " + path); file.transferTo(new File(path + "/" + file.getOriginalFilename())); return "redirect:/index.jsp"; } }
- 文件下载。
@Controller public class FileUploadController { @GetMapping("/download") public String download(HttpServletRequest request, HttpServletResponse response) throws IOException { String s = "E:\\Temp" + File.separator + "update"; String fileName = "笔记.txt"; // 设置响应头 response.reset(); // 设置页面不缓存,情况buffer。 response.setCharacterEncoding("UTF-8"); response.setContentType("multipart/form-data"); //二进制传出数据 response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8")); File file = new File(s, fileName); InputStream inputStream = new FileInputStream(file); ServletOutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inputStream.read()) != -1) { outputStream.write(buffer, 0, len); outputStream.flush(); } outputStream.close(); inputStream.close(); return null; } }