当前位置: 首页 > wzjs >正文

株洲市建设局网站毛局长潍坊网站建设建站

株洲市建设局网站毛局长,潍坊网站建设建站,直播营销策略有哪些,开发网站公司门户网站问题 由于参与的项目有出海需求,即需要给外国人使用,即:需要支持i18n(Internationalization的缩写,共20个字母,除去首尾两个字母,中间有18个,故简称i18n)。 本来是好的…

问题

由于参与的项目有出海需求,即需要给外国人使用,即:需要支持i18n(Internationalization的缩写,共20个字母,除去首尾两个字母,中间有18个,故简称i18n)。

本来是好的,非常简单的Controller接口,在增加字段后,突然爆出StackOverflowError异常:

org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowErrorat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1087)at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)at javax.servlet.http.HttpServlet.service(HttpServlet.java:555)

排查

直接请教ChatGPT,给出如下几种可能导致Controller层接口StackOverflowError异常的场景:

  • Controller方法导致无限递归:直接或间接调用自己
  • JSON序列化导致无限递归:Controller返回的对象包含双向引用,Jackson序列化时可能会陷入无限递归。
@Data
@Entity
public class User {@Idprivate Long id;private String name;@OneToMany(mappedBy = "user")private List<Order> orders;
}@Data
@Entity
public class Order {@Idprivate Long id;private String product;@ManyToOneprivate User user; // 双向引用
}

当User关联Order,Order也关联User,Jackson解析时会无限嵌套,导致StackOverflowError。

解决方案
使用@JsonManagedReference和@JsonBackReference解决循环引用:

@Data
@Entity
public class User {@Idprivate Long id;private String name;@OneToMany(mappedBy = "user")@JsonManagedReferenceprivate List<Order> orders;
}@Data
@Entity
public class Order {@Idprivate Long id;private String product;@ManyToOne@JsonBackReferenceprivate User user;
}

或使用@JsonIgnore:

@ManyToOne
@JsonIgnore
private User user;
  • AOP拦截器陷入无限调用:错误使用Spring AOP或拦截器,可能会导致方法被无限调用;
  • 错误的toString()方法:实体类toString()方法递归调用自身字段。

四种可能性,第二种可能性最大;于是将问题定位到JSON序列化上。

我的Controller层接口,返回对象(即responseBody)并没有包含双向引用;于是将注意力转移到接口的requestBody上。

定位

经过分析,是我在@RequestBody标注的Dto实体类里新增一个Locale字段:

@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
@ApiModel(description = "消息创建请求体")
public class MessageCreateDto {private Locale locale;
}

去掉这个字段,就不再有StackOverflowError异常。

方案

定位到问题后,怎么解决问题呢?

还是直接请教ChatGPT,给出的分析:

Locale本身不是一个普通的Java Bean,它没有默认的无参构造方法,并且Jackson可能无法正确解析它,导致JSON反序列化时进入递归调用,最终导致StackOverflowError。

给出的几种解决方案:

方案一:使用@JsonCreator和@JsonValue

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;public class MessageCreateDto {private Locale locale;@JsonCreatorpublic static Locale fromString(String value) {// 解析 "en_US" => Locale("en", "US")return Locale.forLanguageTag(value.replace('_', '-'));}@JsonValuepublic String toJson() {// 让 Jackson 以 "en-US" 格式序列化return locale.toLanguageTag();}
}

经过验证:并没有解决问题。

方案二:自定义Jackson反序列化器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;public class LocaleDeserializer extends JsonDeserializer<Locale> {@Overridepublic Locale deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {String localeStr = p.getText();return Locale.forLanguageTag(localeStr.replace('_', '-'));}
}

然后在实体类加上注解:

	@JsonDeserialize(using = LocaleDeserializer.class)@JsonSerialize(using = LocaleSerializer.class)private Locale locale;

经过验证:并没有解决问题。

再加上序列化器,还是有StackOverflowError异常。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;public class LocaleSerializer extends JsonSerializer<Locale> {@Overridepublic void serialize(Locale locale, JsonGenerator gen, SerializerProvider serializers) throws IOException {if (locale != null) {// 格式化为 "en-US" 这种形式,而不是 "en_US"gen.writeString(locale.toLanguageTag());} else {gen.writeNull();}}
}

方案三:手动转换String

public class MessageCreateDto {private String projectId;// 直接使用Locale类型,Jackson反序列化报错StackOverflowErrorprivate String locale;public Locale getLocale() {return Locale.forLanguageTag(locale.replace('_', '-'));}
}

经过验证,此方案可行。

反思

上面的方案三虽然可以解决问题。

但是!!

遗留问题:如果我有5个Java应用,每个应用都有20~30个不等的Controller层接口需要支持i18n,那我得在每个应用,每个Controller层接口里加上String locale字段,然后再增加一个getLocale方法么?

稍微熟悉HTTP,或有一点点前端开发经验,或使用F12快捷键查看过Chrome控制台,就知道有个accept-language HTTPheader:
在这里插入图片描述
因此,不是加字段,而是:

  • 前端在全局配置文件里设置accept-language
  • 所有请求接口里自动带上此header;
  • 后端接口按需解析HTTP header,然后做i18n处理。

题外话

zh_CN和zh-CN

关于Locale,到底是使用下划线(即,_)还是横杠(即,-,专业说法,其实是减号连字符

参考zh-CN还是zh_CN。

另外Java API也该出它的立场,zh_CN是老式写法,zh-CN才是推荐的写法。如下图所示,有一个replace动作:
在这里插入图片描述

Locale.US.toString()和Locale.US.toLanguageTag()

前者是老式写法(中间有空格),后者是新式写法:
在这里插入图片描述

参考

  • ChatGPT

文章转载自:

http://Pt8DJkTc.mbpfk.cn
http://LHpYkdJP.mbpfk.cn
http://tw160qce.mbpfk.cn
http://MUqWzcsN.mbpfk.cn
http://fEHpqfxs.mbpfk.cn
http://7DsHUa2u.mbpfk.cn
http://dpII219m.mbpfk.cn
http://Jw2rtcAg.mbpfk.cn
http://jddZVPJj.mbpfk.cn
http://DDditEXn.mbpfk.cn
http://ZGVQ6eWk.mbpfk.cn
http://D7gPP5rm.mbpfk.cn
http://YCR0kM6t.mbpfk.cn
http://m1WTGj5t.mbpfk.cn
http://6qbST1Dk.mbpfk.cn
http://u24Uk84Y.mbpfk.cn
http://S8J5d0Ku.mbpfk.cn
http://4Ec7lJV7.mbpfk.cn
http://ZEgSrKO4.mbpfk.cn
http://4826nDgJ.mbpfk.cn
http://L4PSkJeu.mbpfk.cn
http://B0DsXnBV.mbpfk.cn
http://G8nd9sku.mbpfk.cn
http://mmY8IUKi.mbpfk.cn
http://cuVn2FhT.mbpfk.cn
http://0h3ZaHWv.mbpfk.cn
http://aEnDt3Oh.mbpfk.cn
http://WSW6FTlU.mbpfk.cn
http://DtycSdt7.mbpfk.cn
http://EmuoATaG.mbpfk.cn
http://www.dtcms.com/wzjs/759662.html

相关文章:

  • 桂阳 网站建设织梦dedecms蓝色培训机构模板教育学校学院整站php网站源码
  • 青岛做商城网站互联网之光博览会参展企业
  • 苏州诶茵诶公司网站wordpress 无刷新跳转
  • 网页制作网站知识移动网站视频主持人网
  • 高校学校网站建设软文营销平台
  • 网站建设的页面要求发布外链的平台有哪些
  • 网站前置审批 公司名称淄博网站制作高端服务
  • 在线ftp传网站文件安徽国贸网站建设
  • 西华县住房和城乡建设局网站wordpress 导航 插件
  • 私有云可以做网站网站接入服务商查询
  • 网站的广度百度极速版app下载安装
  • 昆明传媒网站建设微信开放平台appid
  • 公司网站方案建网站免费空间
  • 网址站点异常怎么解决百度关键词策划和seo的优化
  • wordpress建站全教程一线城市做网站工资有多少钱
  • 建立企业网站的技能wordpress单页面代码
  • 像美团这种网站怎么做的asp艺术学校网站源码
  • 网站方案策划书18000字怎么查一个网站是什么程序做的
  • 大连html5网站建设平度市城乡建设局网站
  • 惠州网站设计定制绍兴网站设计
  • 用什么建网站 cms大桥石化集团网站谁做的
  • 个人域名网站网站app下载大全
  • 兴文移动网站建设网站建设推广哪家专业
  • 网站业务怎么做的wordpress 打商插件
  • 做网站签订合同建设电影网站视频
  • 一个企业建设网站的目的建立网站
  • 东莞英文网站建设可口可乐网络营销推广方案
  • 优质专业建设申报网站网站建设用款
  • 服装织梦网站源码网址大全123上网导航
  • 怎么做网站建设赚钱wordpress php缓存