From fa206e8acc0f07dc9945945466a89a9b9ab97edd Mon Sep 17 00:00:00 2001 From: ReaJason Date: Sat, 5 Apr 2025 12:27:50 +0800 Subject: [PATCH] refactor: use react router --- .../boot/controller/ConfigController.java | 41 +++---- .../boot/controller/GeneratorController.java | 11 +- web/bun.lockb | Bin 229188 -> 202996 bytes web/package.json | 21 ++-- .../layouts/root-layout.tsx} | 11 +- web/src/main.tsx | 24 +--- web/src/{routes => pages}/index.tsx | 105 ++++++++---------- web/src/providers/query-client-provider.tsx | 15 +++ web/src/routeTree.gen.ts | 86 -------------- web/src/router.tsx | 22 ++++ web/src/utils/transformer.ts | 24 +++- web/vite.config.ts | 3 +- 12 files changed, 151 insertions(+), 212 deletions(-) rename web/src/{routes/__root.tsx => components/layouts/root-layout.tsx} (86%) rename web/src/{routes => pages}/index.tsx (59%) create mode 100644 web/src/providers/query-client-provider.tsx delete mode 100644 web/src/routeTree.gen.ts create mode 100644 web/src/router.tsx diff --git a/boot/src/main/java/com/reajason/javaweb/boot/controller/ConfigController.java b/boot/src/main/java/com/reajason/javaweb/boot/controller/ConfigController.java index f6194a06..4f3b90d5 100644 --- a/boot/src/main/java/com/reajason/javaweb/boot/controller/ConfigController.java +++ b/boot/src/main/java/com/reajason/javaweb/boot/controller/ConfigController.java @@ -1,11 +1,9 @@ package com.reajason.javaweb.boot.controller; -import com.reajason.javaweb.boot.entity.Config; import com.reajason.javaweb.memshell.Packers; import com.reajason.javaweb.memshell.Server; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.server.AbstractShell; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -20,8 +18,28 @@ import java.util.*; @RequestMapping("/config") @CrossOrigin("*") public class ConfigController { + + @RequestMapping("/servers") + public Map> getServers() { + Map> servers = new LinkedHashMap<>(); + for (Server server : Server.values()) { + if (server.getShell() != null) { + Set supportedShellTypes = server.getShell().getShellInjectorMapping().getSupportedShellTypes(); + servers.put(server.name(), supportedShellTypes.stream().toList()); + } + } + return servers; + } + + @RequestMapping("/packers") + public List getPackers() { + return Arrays.stream(Packers.values()) + .filter(packers -> packers.getParentPacker() == null) + .map(Packers::name).toList(); + } + @RequestMapping - public ResponseEntity config() { + public Map> config() { Map> coreMap = new HashMap<>(16); for (Server value : Server.values()) { AbstractShell shell = value.getShell(); @@ -38,21 +56,6 @@ public class ConfigController { } coreMap.put(value.name(), map); } - Config config = new Config(); - Map> servers = new LinkedHashMap<>(); - for (Server server : Server.values()) { - if (server.getShell() != null) { - Set supportedShellTypes = server.getShell().getShellInjectorMapping().getSupportedShellTypes(); - servers.put(server.name(), supportedShellTypes.stream().toList()); - } - } - config.setServers(servers); - config.setCore(coreMap); - config.setPackers( - Arrays.stream(Packers.values()) - .filter(packers -> packers.getParentPacker() == null) - .map(Packers::name).toList() - ); - return ResponseEntity.ok(config); + return coreMap; } } \ No newline at end of file diff --git a/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java b/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java index 4132e846..623d4a64 100644 --- a/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java +++ b/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java @@ -1,8 +1,8 @@ package com.reajason.javaweb.boot.controller; -import com.reajason.javaweb.memshell.MemShellGenerator; import com.reajason.javaweb.boot.dto.GenerateRequest; import com.reajason.javaweb.boot.dto.GenerateResponse; +import com.reajason.javaweb.memshell.MemShellGenerator; import com.reajason.javaweb.memshell.config.GenerateResult; import com.reajason.javaweb.memshell.config.InjectorConfig; import com.reajason.javaweb.memshell.config.ShellConfig; @@ -10,7 +10,6 @@ import com.reajason.javaweb.memshell.config.ShellToolConfig; import com.reajason.javaweb.memshell.packer.AggregatePacker; import com.reajason.javaweb.memshell.packer.Packer; import com.reajason.javaweb.memshell.packer.jar.JarPacker; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.Base64; @@ -24,18 +23,18 @@ import java.util.Base64; @CrossOrigin("*") public class GeneratorController { @PostMapping - public ResponseEntity generate(@RequestBody GenerateRequest request) { + public GenerateResponse generate(@RequestBody GenerateRequest request) { ShellConfig shellConfig = request.getShellConfig(); ShellToolConfig shellToolConfig = request.parseShellToolConfig(); InjectorConfig injectorConfig = request.getInjectorConfig(); GenerateResult generateResult = MemShellGenerator.generate(shellConfig, injectorConfig, shellToolConfig); Packer packer = request.getPacker().getInstance(); if (packer instanceof JarPacker) { - return ResponseEntity.ok(new GenerateResponse(generateResult, Base64.getEncoder().encodeToString(((JarPacker) packer).packBytes(generateResult)))); + return new GenerateResponse(generateResult, Base64.getEncoder().encodeToString(((JarPacker) packer).packBytes(generateResult))); } else if (packer instanceof AggregatePacker) { - return ResponseEntity.ok(new GenerateResponse(generateResult, ((AggregatePacker) packer).packAll(generateResult))); + return new GenerateResponse(generateResult, ((AggregatePacker) packer).packAll(generateResult)); } else { - return ResponseEntity.ok(new GenerateResponse(generateResult, packer.pack(generateResult))); + return new GenerateResponse(generateResult, packer.pack(generateResult)); } } } \ No newline at end of file diff --git a/web/bun.lockb b/web/bun.lockb index c577063858d642dbdd51b03bcc841b45759acc4e..c580d2fafba4cd9ae26f56c7247b101ed2a040a7 100755 GIT binary patch delta 38950 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 K;btO!Anmf zI%RKs#U2TEjoWH&b~Jbt^YU%zBbJ{_d}HOSYkk}t@y;)yO?F9a_S7-*f{za^9>wC_ z`%V|jr^ZBms~y|yNpYp9fq4?$8^w%Hn5GLb;fLhq78aQD3}T{F(ISs^(RJ=nP(|hU zoeiT3O?l&L7mAG4N<~3wrqKntx!L*DdnZ;qQwv$E#%9yl0z*NDDaVvg#oL(+RTi>7 zG-d;{uXu4Z`^exG7F>`%Ubr1;$j`~m1$4B@Twuz{EP!ee6^&Q2L006rfpx3MTFchp z2Q$+Y(?wo@BLc0b^|9&2_mU-|PdJJ^b>npTq=i%KOs$|VLYmk=H!!o|9! zmul7$3|or{R}uKvh(fu3@o@{LFkfrACun;G^Xyk$Xl+^f1-W^qf=u%`!CoGw}EeBETf z5*Pszp6H}#+BAkW_pYu!sMTK~CzSkbb+I&WHS?|GqOw5Ai?}VgSXdK%Uzl$)@X%&} zBbxHeso4fm@n5GfkEnWxsJPQu`liaA6C&1Ht2ZG*wY(l%*5Wo)bxv%}&Z+XS zn!Qw`SgwLLEoVMK^1WVeZ|RCJ0Jzu7Z6n>dl>z|GeTV7&YL?}5KJhNEgvvLBk#;Hb zbC8Ow0Yrk6crh8};s=9pd!E7$v*sOZ8BK^S0E(s(-VEaPU9O$tY9d82O3Q65AV7@* zF$#=Jp|H~|gck2)w%RaSyOU*VBP*PCv41(x5677|%AOuaI5M7Ko@8^HHKyw)m;)_2 z$(oQK{}gwYH5EU7bpl@vz<-U%@+6DlpDd~91Zz+6Cz+r4I_Lzz7)-&{Ugw`d4C(w1 zc$c1nJb-P<0^?0AvpK`O>ATa+x9YWhO|T`sc8d8|mBm$k@}!ZcWhsJWXxg%hDm0-* zwO6!Fk>Wtt&d6253Qg_IxoLc~^M^sWs7Nc$!fN;i=6-tNJZn;M;VcVmK#$fi4{Guz zb8jGmv=>=2-Mz}}Dq=6OuN}z#2j)|u|D84Upe2oU9u+-ob&quxnERutyQ8i<9T~@b zih2#jIz<+G4G95?;G1<67*=Dw8VOR29|e-=Uf25P3x&Jd8HI&pdtQcks#|p%>qT zL{Lb>bQVI*E;3&qtnmTC|J-x2wCCh>6S9r`VY%kvnd!tsJQe@SEJEcX;Hx9Rh=mO2 z%QK-%XyUryyEY``nCX?`0lU1^a+rr_(9u1FRvX964M|Scru#Q2vYxtSPG! zzk486fPw(|v!ITLR_9WqU_+?dUp02Ab}K5e&^cAfkV^G(fuKS_rP2(c;GKUf z1%e*u_OdD&Xn_qq)aj}WC$L=Ft=LH@_@q)P;4K*u2=^lG{X1!Dv!c!b$YU0#jL28oz9tFnu9qiw3)6cdD-dgw9#bOOlP3tM!HC? zk(S?pOLMt2uCdOuszS?%nju*Uy=XywB)SN}FVv(Wme=7x8P^> @@ -42,4 +39,4 @@ function RootComponent() { ); -} +} \ No newline at end of file diff --git a/web/src/main.tsx b/web/src/main.tsx index 4a293442..1cfa2676 100644 --- a/web/src/main.tsx +++ b/web/src/main.tsx @@ -1,37 +1,23 @@ -import { RouterProvider, createRouter } from "@tanstack/react-router"; import ReactDOM from "react-dom/client"; -import { routeTree } from "./routeTree.gen"; import "./index.css"; import { TailwindIndicator } from "@/components/tailwind-indicator.tsx"; import { env } from "@/config.ts"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { I18nextProvider } from "react-i18next"; import i18n from "./i18n/i18n"; - -const queryClient = new QueryClient(); - -const router = createRouter({ - routeTree, - basepath: env.BASE_PATH, - defaultPreload: "intent", -}); - -declare module "@tanstack/react-router" { - interface Register { - router: typeof router; - } -} +import { RouterProvider } from "react-router-dom"; +import { router } from "./router"; +import { QueryProvider } from "./providers/query-client-provider"; const rootElement = document.getElementById("app") as HTMLElement; if (!rootElement.innerHTML) { const root = ReactDOM.createRoot(rootElement); root.render( - + {env.MODE !== "production" && } - , + ); } diff --git a/web/src/routes/index.tsx b/web/src/pages/index.tsx similarity index 59% rename from web/src/routes/index.tsx rename to web/src/pages/index.tsx index dffcd319..658e0614 100644 --- a/web/src/routes/index.tsx +++ b/web/src/pages/index.tsx @@ -10,41 +10,56 @@ import { ConfigResponseType, GenerateResponse, GenerateResult, + MainConfig, + PackerConfig, + ServerConfig, ShellToolType, } from "@/types/shell.ts"; -import { transformToPostData } from "@/utils/transformer.ts"; +import { customValidation, transformToPostData } from "@/utils/transformer.ts"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useQuery } from "@tanstack/react-query"; -import { createFileRoute } from "@tanstack/react-router"; import { LoaderCircle, WandSparklesIcon } from "lucide-react"; import { useState, useTransition } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; +import { useQuery } from "@tanstack/react-query"; -export const Route = createFileRoute("/")({ - component: IndexComponent, -}); +export default function IndexPage() { + const { data: serverConfig } = useQuery({ + queryKey: ["serverConfig"], + queryFn: async () => { + const response = await fetch(`${env.API_URL}/config/servers`); + return await response.json(); + }, + }); -function IndexComponent() { - const { data } = useQuery({ - queryKey: ["config"], + const { data: mainConfig } = useQuery({ + queryKey: ["mainConfig"], queryFn: async () => { const response = await fetch(`${env.API_URL}/config`); return await response.json(); }, }); + + const { data: packerConfig } = useQuery({ + queryKey: ["packerConfig"], + queryFn: async () => { + const response = await fetch(`${env.API_URL}/config/packers`); + return await response.json(); + }, + }); + const { t } = useTranslation(); const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { - server: "", + server: "Tomcat", targetJdkVersion: "50", debug: false, bypassJavaModule: false, shellClassName: "", shellTool: "Godzilla", - shellType: "", + shellType: "Listener", urlPattern: "/*", godzillaPass: "pass", godzillaKey: "key", @@ -64,40 +79,11 @@ function IndexComponent() { const [packMethod, setPackMethod] = useState(""); const [isActionPending, startTransition] = useTransition(); - function customValidation(values: FormSchema) { - if (values.shellType.endsWith("Servlet") && (values.urlPattern === "/*" || !values.urlPattern)) { - toast.warning(t("tips.servletUrlPattern")); - return false; - } - - if (values.shellType.endsWith("ControllerHandler") && (values.urlPattern === "/*" || !values.urlPattern)) { - toast.warning(t("tips.controllerUrlPattern")); - return false; - } - - if ( - (values.shellType === "HandlerMethod" || values.shellType === "HandlerFunction") && - (values.urlPattern === "/*" || !values.urlPattern) - ) { - toast.warning(t("tips.handlerUrlPattern")); - return false; - } - - if (values.shellTool === ShellToolType.Custom && !values.shellClassBase64) { - toast.warning(t("tips.customShellClass")); - return false; - } - return true; - } - - async function onSubmit(values: FormSchema) { + const onSubmit = async (data: FormSchema) => { startTransition(async () => { - if (!customValidation(values)) { - return; - } - - const postData = transformToPostData(values); try { + customValidation(t, data); + const postData = transformToPostData(data); const response = await fetch(`${env.API_URL}/generate`, { method: "POST", headers: { @@ -105,31 +91,30 @@ function IndexComponent() { }, body: JSON.stringify(postData), }); - await new Promise((resolve) => setTimeout(resolve, 200)); - if (response.ok) { - const json: GenerateResponse = await response.json(); - setPackResult(json.packResult); - setAllPackResults(json.allPackResults); - setGenerateResult(json.generateResult); - setPackMethod(values.packingMethod); - toast.success(t("success.generated")); - } else { + + if (!response.ok) { const json: APIErrorResponse = await response.json(); toast.error(t("errors.generationFailed", { error: json.error })); } - } catch (err) { - const error = err as Error; - toast.error(t("errors.generationFailed", { error: error.message })); + + const result = (await response.json()) as GenerateResponse; + setGenerateResult(result.generateResult); + setPackResult(result.packResult); + setAllPackResults(result.allPackResults); + setPackMethod(data.packingMethod); + toast.success(t("success.generated")); + } catch (error) { + toast.error(t("errors.generationFailed", { error: (error as Error).message })); } }); - } + }; return (
- +
- - + +