gpt4 book ai didi

java - 具有 Vaadin UI 的 Spring Boot 应用程序不断刷新屏幕

转载 作者:行者123 更新时间:2023-11-30 09:59:21 26 4
gpt4 key购买 nike

我有一个启动应用程序,我正在向其中添加一些 crud 屏幕。我决定使用 Vaadin,在我将它部署到多节点生产环境之前,它似乎工作得很好。一旦进入产品环境,屏幕就会无缘无故地不断刷新。例如,在一个屏幕中有一个网格,当单击一行时,会弹出一个显示项目详细信息的对话框。但是一旦弹出对话框,页面就会刷新无数次。

此论坛主题在这里 https://vaadin.com/forum/thread/17586129/routerlayout-causing-page-refresh是我正在使用的相同布局的示例,并描述了一个非常相似的问题。

我有一个扩展 VerticalLayout 的基本抽象类,所有具体类都扩展了这个基本抽象类。每个具体类定义自己的路线并使用通用布局类。

我已经联系了 gitter、vaadin 论坛并在 github 中打开了一个错误,但据我所知,Vaadin 的任何人都不想回应任何事情。

以下是我使用的所有版本:Vaadin Flow 版本:14Java版本:12.0.1+12操作系统版本:Mac 10.14.5浏览器版本:Fire Fox 70.0.1、Chrome 78.0.3904.97

我的实现代码片段:主视图

@Slf4j
@RoutePrefix("v1/crud")
@Theme(value = Material.class, variant = Material.DARK)
public class MainView extends Div implements RouterLayout {
private H1 h1 = new H1("Vaadin Crud UI");
private HorizontalLayout header = new HorizontalLayout(h1);
private Div content = new Div();
private ApplicationContext context;

@Inject
public MainView(ApplicationContext context) {
this.context = context;
setSizeFull();
h1.setWidthFull();
content.setWidthFull();
header.setWidthFull();
header.setAlignItems(FlexComponent.Alignment.CENTER);
VerticalLayout navigationBar = new VerticalLayout();
navigationBar.setWidth("25%");

navigationBar.add(createNavigationButton("Home", VaadinIcon.HOME, ReportTab.class));
navigationBar.add(createNavigationButton("Batch Search", VaadinIcon.SEARCH, BatchSearchTab.class));
... a bunch more buttons
HorizontalLayout layout = new HorizontalLayout(navigationBar, content);
layout.setWidthFull();
VerticalLayout page = new VerticalLayout(header, layout);
page.setWidthFull();
add(page);
}

@Override
public void showRouterLayoutContent(HasElement hasElement) {
if (hasElement != null) {
Element newElement = hasElement.getElement();
if (newElement != null) {
content.removeAll();
content.getElement().appendChild(newElement);
}
}
}

private Button createNavigationButton(String caption, VaadinIcon icon, Class<? extends BaseEditor> editor) {
Button button = new Button(caption, icon.create());
button.addClickListener(event -> UI.getCurrent().navigate(editor));
button.addThemeVariants(ButtonVariant.MATERIAL_CONTAINED);
button.getStyle().set("background-color", "#00819D");
button.setWidthFull();
return button;
}

}

基本组件:

@Slf4j
@Data
@SpringComponent
@UIScope
public abstract class BaseEditor<P, B> extends VerticalLayout {

private final RememberMeService rememberMe;
private final P businessProcess;
protected Binder<B> binder;
protected Dialog editDialog = new Dialog();
protected Button save = new Button("Save", VaadinIcon.CHECK.create());
protected Button close = new Button("Close", VaadinIcon.EXIT.create());
protected Button delete = new Button("Delete", VaadinIcon.TRASH.create());
protected B bean;

private ChangeHandler changeHandler;
private boolean proceed = true;

public BaseEditor(P businessProcess, RememberMeService rememberMe) {
this.rememberMe = rememberMe;
this.businessProcess = businessProcess;
save.addClickListener(e -> save());
delete.addClickListener(e -> delete());
}

public abstract void delete();

public abstract void save();

protected abstract Component getContent();

protected void edit(B e) {
bean = e;
editDialog.open();
getBinder().setBean(e);
}

protected void initEditorPanel(Component... components) {
HorizontalLayout actions = new HorizontalLayout(save, close, delete);
VerticalLayout data = new VerticalLayout(components);
data.add(actions);
editDialog.removeAll();
editDialog.add(data);
getBinder().bindInstanceFields(this);
close.addClickListener(e -> editDialog.close());
}

public interface ChangeHandler {
void onChange();
}

void setChangeHandler(ChangeHandler h) {
changeHandler = h;
}

void errorDialog(String message) {
final Button close = new Button("Close", VaadinIcon.CLOSE.create());
H3 h3 = new H3(message);
final Dialog errorDialog = new Dialog(h3, close);
errorDialog.open();
close.addClickListener(e -> errorDialog.close());
}

BaseEditor filter(Predicate<B> predicate) {
Objects.requireNonNull(predicate);
proceed = predicate.test(bean);
return this;
}

void buttonConsumer(Consumer<B> consumer) {
if (!proceed) {
proceed = true;
return;
}
try {
consumer.accept(bean);
} catch (Exception e) {
errorDialog(e.getMessage());
} finally {
editDialog.close();
getChangeHandler().onChange();
}
}

void either(Consumer<B> whenTrue, Consumer<B> whenFalse) {
try {
if (proceed) {
whenTrue.accept(bean);
} else {
whenFalse.accept(bean);
}
} catch (Exception e) {
errorDialog(e.getMessage());
} finally {
proceed = true;
editDialog.close();
getChangeHandler().onChange();
}
}
}

混凝土构件:

@Slf4j
@Route(value = "search/batch", layout = MainView.class)
public class BatchSearchTab extends BaseEditor<BatchService, Batch> {
private TextField searchField1;
private TextField searchField2;

public BatchSearchTab(BatchService businessProcess, RememberMeService rememberMe) {
super(businessProcess, rememberMe);
binder = new Binder<>(Batch.class);
save.setIcon(VaadinIcon.REPLY.create());
save.setText("Replay");
delete.setIcon(VaadinIcon.CLOSE.create());
delete.setText("Cancel");
getContent();
}

@Override
public void delete() {
buttonConsumer(b -> getBusinessProcess().cancelBatch(b.getBatchId(), b.getUserAgent()));
}

@Override
public void save() {
filter(b -> b.isReplayable()).buttonConsumer(b -> getBusinessProcess().buildAndSendFile((getBean())));
}

@Override
public void edit(Batch batch) {
HorizontalLayout actions = new HorizontalLayout();
H2 h2 = new H2();
if (batch.isReplayable()) {
h2.setText("Would you like to replay the following.");
actions.add(save, delete, close);
} else {
h2.setText("This record is not eligible for replay.");
actions.add(close);
}

Label batchId = new Label("Correlation Id: " + batch.getBatchId());
Label txnCount = new Label("Transaction Count: " + batch.getTotalTxns());
Label txnAmount = new Label("Total: " + batch.getTotalBatchAmount());
VerticalLayout data = new VerticalLayout(h2, batchId, txnCount, txnAmount, actions);
data.add(actions);
editDialog.removeAll();
editDialog.add(data);
close.addClickListener(e -> editDialog.close());
editDialog.open();
getBinder().setBean(batch);
}

@Override
protected Component getContent() {
final H2 h2 = new H2("Locate Batches");
searchField1 = new TextField("Batch Code");
searchField2 = new TextField("User Agent");
searchField2.addKeyPressListener(Key.ENTER, e -> keyPressListener());
Button searchBtn = new Button("Search", VaadinIcon.SEARCH.create());
HorizontalLayout search = new HorizontalLayout(searchField1, searchField2);
searchBtn.addClickListener(e -> {
search(searchField1.getValue(), searchField2.getValue());
});
add(h2, search, searchBtn);
return this;
}

private void search(String code, String userAgent) {
log.info("Searching {} and {}", code, userAgent);
List<Batch> batches =
getBusinessProcess().getBatchesForUserAgent(code, userAgent, 60);
log.info("Found {} batches", batches.size());
if (batches.size() > 0) {
buildGrid(batches, "BatchId", "totalTxns", "totalBatchAmount", "status");
} else {
errorDialog("No Records found for criteria");
}
}

private void keyPressListener() {
String code = StringUtils.isNotBlank(searchField1.getValue()) ? searchField1.getValue() : null;
if (StringUtils.isNotBlank(searchField2.getValue())) {
search(code, searchField2.getValue());
}
}

private void buildGrid(Collection<Batch> records, String... columns) {
Component result;
if (records.size() == 0) {
result = new Label("NO REPORT DATA AVAILABLE.");
} else {
final Grid<Batch> grid = new Grid<>(Batch.class);
grid.setHeightByRows(records.size() < 10);
grid.setColumns(columns);
grid.setItems(records);
grid.setWidthFull();
grid.asSingleSelect().addValueChangeListener(l -> Optional.ofNullable(l.getValue()).ifPresent(this::edit));
result = grid;
}
if (getComponentCount() < 3) {
add(result);
} else {
replace(getComponentAt(2), result);
}
}

private void loadData(String code, String userAgent) {
if (StringUtils.isNotBlank(code)) {
search(null, userAgent);
} else {
search(code, userAgent);
}
}
}

最佳答案

免责声明:通过 IRC 发现了一些进一步的事实

问题的答案与 OP 在循环负载平衡器后面运行多个应用程序实例有关。客户端访问随机服务器,因此没有会​​话在那里运行。

这个问题的解决方案是拥有一个共享 session 存储,理想情况下是在现有 session 上分配负载均衡器,这样“热”后端服务器就会受到攻击。

关于java - 具有 Vaadin UI 的 Spring Boot 应用程序不断刷新屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59000652/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com