SpringMVC
MVC架构
依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
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">
<servlet>
<servlet-name>mvc_shine</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml</param-value>
</init-param>
<!--变成饿汉式加载 可选的配置-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc_shine</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>
</web-app>
后端控制器
@Controller声明控制器
@RequestMapping("/heello")
配置解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
SpringMVC.xml全部配置
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.alibaba.com/schema/stat"
xmlns:mvc1="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<mvc:annotation-driven>
<!-- 安装FastJson,转换器 -->
<mvc:message-converters>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 声明转换类型:json -->
<property name="supportedMediaTypes">
<list>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/><!--通过${}来取配置文件的值-->
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="initialSize" value="${jdbc.init}"/>
<property name="minIdle" value="${jdbc.minIdle}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations">
<list>
<value>classpath:com/lang/dao/*.xml</value>
</list>
</property>
<property name="typeAliasesPackage" value="com.lang.entity"/>
</bean>
<bean id="mapperScannerConfiguer9" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--dao接口所在的包-->
<property name="basePackage" value="com.lang.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txManager" transaction-manager="tx">
<tx:attributes>
<!--以User为结尾的方法-->
<tx:method name="*User" read-only="true" isolation="READ_COMMITTED" rollback-for="Exception"/>
<!--以query开头的方法,切入此方法时,采用对应事务实行-->
<tx:method name="query*" propagation="SUPPORTS"/>
<!--剩余所有方法-->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--额外增加一个handle,且其requestMapping:“/**”-->
<mvc1:default-servlet-handler/>
<context:component-scan base-package="com.lang" ></context:component-scan>
<tx:annotation-driven transaction-manager="tx"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
pom.xml全部配置
<?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.lang</groupId>
<artifactId>learn</artifactId>
<version>1.0-SNAPSHOT</version>
<!--设置项目类型 web项目是war java项目是jar-->
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!--更改maven编译规则-->
<resources>
<resource>
<!--资源目录-->
<directory>src/main/java</directory>
<includes>
<include>*.xml</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
转发与重定向
转发
直接return “路径”或者 “forward:/hello.jsp”
重定向
redirect:路径
使用规则
一般增删改为了防止用户刷新页面导致重复操作,会选择使用重定向,查询使用转发
静态资源
默认是访问不到的。
Ajax访问数据
<script>
function send_json(){
// ajax, json
var user = {id:1,name:"shine"};
var userJson = JSON.stringify(user);
$.ajax({
url:"${pageContext.request.contextPath}/json/test4",
type:"post",
data:userJson,
contentType:"application/json",
success:function(ret){
alert(ret);
}
})
}
</script>
JSON常用注解
日期
@JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”)
private Date birth;
null属性排除
//@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_EMPTY)//不仅不能为空,且长度不能为0
private List i;
若是i为空,那么就在json中排除该数据,若不为空则添加进json数据
属性名修改
@JsonProperty(“newname”)
自定义序列化
@JsonSerialize(using=xxx.class)
以下是将小数四舍五入两位小数
package com.qf.serialize;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
public class MySerializer extends JsonSerializer<Double> {
@Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// 将Double salary的值 四舍五入
String number = BigDecimal.valueOf(value).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
// 输出 四舍五入后的值
gen.writeNumber(number);
}
}
为金钱加元
package com.qf.serialize;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import java.io.IOException;
import java.lang.reflect.Type;
public class MySerializer2 implements ObjectSerializer {
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
int features) throws IOException {
Double value = (Double) object; // salary属性值
String text = value + "元";// 在salary后拼接 “元”
serializer.write(text); // 输出拼接后的内容
}
}
FastJson的一些属性
package com.qf.entity;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.qf.serialize.MySerializer2;
import java.util.Date;
public class User2 {
@JSONField(serialize = false)
private Integer id;
@JSONField(name="NAME",serialzeFeatures = SerializerFeature.WriteNullStringAsEmpty)
private String name;// ""
@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue)
private String city;// null
@JSONField(format="yyyy/MM/dd")
private Date birth;
@JSONField(serializeUsing = MySerializer2.class)
private Double salary; // 元
public User2(){}
public User2(Integer id, String name, String city, Date birth, Double salary) {
this.id = id;
this.name = name;
this.city = city;
this.birth = birth;
this.salary = salary;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
}
异常解析器
package com.qf.resolver;
import com.qf.ex.MyException1;
import com.qf.ex.MyException2;
import com.qf.ex.MyException3;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 异常解析器
// 任何一个Handler中抛出异常时
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if(e instanceof MyException1){
// error1.jsp
modelAndView.setViewName("redirect:/error1.jsp");
}else if(e instanceof MyException2){
// error2.jsp
modelAndView.setViewName("redirect:/error2.jsp");
}else if(e instanceof MyException3){
// error3.jsp
modelAndView.setViewName("redirect:/error3.jsp");
}else if(e instanceof MaxUploadSizeExceededException){
modelAndView.setViewName("redirect:/uploadError.jsp");
}
return modelAndView;
}
}
拦截器
拦截器需要在mvc.xml配置
用户名登录
package com.qf.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MyInterceptor implements HandlerInterceptor {
// 在handler之前执行
// 再次定义 handler中冗余的功能
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("pre Handle");
// 判断登录状态
HttpSession session = request.getSession();
if(session.getAttribute("state")!=null){
return true;//放行,执行后续的handler
}
// 中断之前,响应请求
response.sendRedirect("/login.jsp");
return false;//中断请求,不再执行后续的handler
}
// 在handler之后执行,响应之前执行
// 改动请求中数据
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("post Handle");
}
// 在视图渲染完毕后,
// 资源回收
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("after Completion");
}
}
文件大小
package com.qf.interceptor;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyFileUploadInterceptor implements HandlerInterceptor {
private Long maxFileuploadSize;
public Long getMaxFileuploadSize() {
return maxFileuploadSize;
}
public void setMaxFileuploadSize(Long maxFileuploadSize) {
this.maxFileuploadSize = maxFileuploadSize;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断上传文件大小 1048576
ServletRequestContext servletRequestContext = new ServletRequestContext(request);
// 文件大小 byte
long l = servletRequestContext.contentLength();
if(l>maxFileuploadSize){
throw new MaxUploadSizeExceededException(maxFileuploadSize);
}
return true;
}
}