08-解决常见问题

nobility 发布于 2022-12-01 05-SpringMVC 2492 次阅读


解决常见问题

格式转化器

局部日期格式转化

@Controller
public class Main {
  @GetMapping("/test")
  @ResponseBody
  public String test(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS") Date date) {
    return "date: " + date;
  }
}
//用于测试的连接
//<a href="${pageContext.request.contextPath}/test?date=1970-01-01 00:00:00.000">/test?date=1970-01-01 00:00:00.000</a>

全局日期格式转化

自定义格式转化器,实现Converter接口,重写convert()方法,优先级低于局部日期转化,这只是个示例,自定义转换器可用于任意类型的转化

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateConverter implements Converter<String, Date> {  //实现Converter接口,泛型表示将String转化为Date类型
  @Override
  public Date convert(String string) {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    try {
      return simpleDateFormat.parse(string);  //返回转化后的日期对象
    } catch (ParseException e) {
      return null;  //解析错误返回null
    }
  }
}

再在Spring全局配置文件applicationContext.xml中更新下面配置

<context:component-scan base-package="com"/>
<mvc:annotation-driven conversion-service="FormattingConversionServiceFactoryBean"/>  <!--指定转换器工厂,之后遇到转换器能转化的就会使用转换器转化-->
<mvc:default-servlet-handler/>

<bean id="FormattingConversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">  <!--创建转换器工厂-->
  <property name="converters">  <!--注入自定义转化器-->
    <set>
      <bean class="com.DateConverter"/>
    </set>
  </property>
</bean>

解决中文乱码

请求中的中文乱码

对于Get请求,Tomcat8及以上版本Get请求参数默认就是UTF-8,Tomcat7需要在Tomcat的server.xml配置文件中找到这项配置:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />,添加一个属性字段URLEncoding="UTF-8",改为这样<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URLEncoding="UTF-8" />即可

对于Post请求,需要在web.xml中配置SpringMVC提供的字符编码过滤器即可,具体如下

<filter>
  <filter-name>characterEncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>  <!--配置字符编码为UTF-8-->
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>characterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>  <!--拦截所有请求-->
</filter-mapping>

响应中的中问乱码

局部解决

在URL映射注解中设置produces属性,可指定Context-Text的值,以@RequestMapping注解为例,因为可添加到类上

@RequestMapping(produces = "text/html;charset=utf-8")
全局解决

在Spring全局配置文件applicationContext.xml中更新下面配置

<context:component-scan base-package="com"/>
<mvc:annotation-driven>  <!--开启此标签的双标签模式-->
  <mvc:message-converters>
    <bean class="org.springframework.http.converter.StringHttpMessageConverter">  <!--指定消息转换器-->
      <property name="supportedMediaTypes">   <!--注入支持的媒体类型-->
        <list>
          <value>text/html;charset=utf-8</value>  <!--html类型-->
          <value>application/json;charset=utf-8</value>  <!--json类型-->
        </list>
      </property>
    </bean>
  </mvc:message-converters>
</mvc:annotation-driven> 
<mvc:default-servlet-handler/>

解决非简单请求接收不到参数问题

需要在web.xml中配置SpringMVC提供的表单内容过滤器即可,具体如下

<filter>
  <filter-name>formContentFilter</filter-name>
  <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>formContentFilter</filter-name>
  <url-pattern>/*</url-pattern>   <!--拦截所有请求-->
</filter-mapping>

解决跨域请求

局部注解方式

在控制器类上使用@CrossOrigin注解,表示该类下的所有映射的URL都支持跨域请求,具体使用如下

@CrossOrigin(origins = {"http://www.baidu.com"})  //origins是一个数组,可指定多个域名
//@CrossOrigin(origins = "*")  //也可使用星号通配符进行全部放行
//@CrossOrigin(origins = {"http://www.baidu.com"},maxAge = 3600)  //maxAge属性表示缓存预检请求缓存时间,可减请服务器的压力,单位秒
@RestController
public class Main {
  //...
}

全局xml方式

在Spring全局配置文件applicationContext.xml中添加下面配置

  <mvc:cors>
    <mvc:mapping path="/prefix/**" allowed-origins="http://www.baidu.com" max-age="3600"/>
    <!--path属性决定了哪些请求路径可以跨域访问,/prefix/** 代表 prefix 父路径下的所有路径-->
     <!--allowed-origins中多个域名使用逗号分隔即可-->
  </mvc:cors>

整合Freemarker

引入freemarker包和spring-context-support整合包

在Spring全局配置文件applicationContext.xml中添加下面配置

<bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
  <property name="contentType" value="text/html;charset=utf-8"/>  <!--设置contentType-->
  <property name="suffix" value=".ftl"/>  <!--指定FreeMarker模板文件的后缀名,在程序中就可省略后缀名-->
</bean>
<bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="templateLoaderPath" value="/WEB-INF/ftl"/>  <!--指定模板文件目录,若代码中不想使用该目录,添加 forward: 前缀即可-->
  <property name="freemarkerSettings">
    <props>
      <prop key="defaultEncoding">UTF-8</prop>  <!--指定Freemarker脚本与数据渲染时使用的字符集-->
    </props>
  </property>
</bean>

使用下面代码测试

@Controller
public class Main {
  @GetMapping("/test")
  public ModelAndView test(Integer id) {
    ModelAndView modelAndView = new ModelAndView("/index");
    //无需添加后缀,以为已经配置过,并且 / 根对应模板文件根目录
    modelAndView.addObject("id", id);
    return modelAndView;
    ///index.ftl中内容为:<h1>${id}</h1>
  }
}
加油啊!即便没有转生到异世界,也要拿出真本事!!!\(`Δ’)/
最后更新于 2022-12-01