国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity UGUI的Physi會隨機改變csRaycaster (物理射線檢測)組件的介紹及使用

這篇具有很好參考價值的文章主要介紹了Unity UGUI的Physi會隨機改變csRaycaster (物理射線檢測)組件的介紹及使用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

寫在前面

這里只介紹liteflow的簡單基礎使用以及作者對liteflow進行可視化擴展的相關闡述

一、背景及意義

背景:對于擁有復雜業(yè)務邏輯的系統(tǒng)承載著核心業(yè)務邏輯,這些核心業(yè)務邏輯涉及內部邏輯運算,緩存操作,持久化操作,外部資源調取,內部其他系統(tǒng)RPC調用等等。項目幾經易手,維護的成本就會越來越高。各種硬代碼判斷,分支條件越來越多。代碼的抽象,復用率也越來越低,各個模塊之間的耦合度很高。一小段邏輯的變動,會影響到其他模塊,需要進行完整回歸測試來驗證。如要靈活改變業(yè)務流程的順序,則要進行代碼大改動進行抽象,重新寫方法。實時熱變更業(yè)務流程,幾乎很難實現(xiàn)

意義:邏輯解耦、提高擴展性、降低維護成本、能力充分復用、流程靈活編排

二、常用流程編排框架

liteflow(開源) asyncTool(開源) JDEasyFlow(開源) disruptor
介紹 LiteFlow是一個非常強大的現(xiàn)代化的規(guī)則引擎框架,融合了編排特性和規(guī)則引擎的所有特性。如果你要對復雜業(yè)務邏輯進行新寫或者重構,用LiteFlow最合適不過。它是一個編排式的規(guī)則引擎框架,組件編排,幫助解耦業(yè)務代碼,讓每一個業(yè)務片段都是一個組件。 解決任意的多線程并行、串行、阻塞、依賴、回調的并發(fā)框架,可以任意組合各線程的執(zhí)行順序,帶全鏈路回調和超時控制。 通用流程編排技術組件,適用于服務編排、工作流、審批流等場景
地址 LiteFlow asyncTool: 解決任意的多線程并行、串行、阻塞、依賴、回調的并行框架,可以任意組合各線程的執(zhí)行順序,帶全鏈路執(zhí)行結果回調。多線程編排一站式解決方案。來自于京東主App后臺。 流程編排、如此簡單-通用流程編排組件JDEasyFlow介紹-京東云開發(fā)者社區(qū)
優(yōu)點 復雜業(yè)務流程編排、社區(qū)成熟活躍 基于jdk8 CompletableFuture、輕量級 簡單、靈活、易擴展 基于生產-消費模型、無鎖設計
缺點 開源框架較重,有一定學習成本 新框架穩(wěn)定性待驗證 較為底層,針對業(yè)務場景需要二次封裝
示例 liteflow-example: liteflow的一個業(yè)務示例工程https://gitee.com/bryan31/liteFlow

三、liteflow基礎使用

1.添加依賴jar包

<dependency>
	<groupId>com.yomahub</groupId>
    <artifactId>liteflow-spring</artifactId>
	<version>2.10.4</version>
</dependency>

2.定義組件

定義組件和實現(xiàn)某些組件,注冊進上下文

@Component("a")
public class ACmp extends NodeComponent {

    @Override
    public void process() {
        //do your business
    }
}

3.配置

添加對應的配置類及配置文件

Spring xml中的配置

<context:component-scan base-package="com.yomahub.flowtest.components" />

<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>

<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>

<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
    <property name="ruleSource" value="config/flow.el.xml"/>
</bean>

<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
    <property name="liteflowConfig" ref="liteflowConfig"/>
</bean>

<!-- 如果上述enableLog為false,下面這段也可以省略 -->
<bean class="com.yomahub.liteflow.monitor.MonitorBus">
    <property name="liteflowConfig" ref="liteflowConfig"/>
</bean>

4.規(guī)則文件的定義

--流程的定義(第3步中l(wèi)iteflowConfig指定了規(guī)則文件為config/flow.xml),所以需要在resources下新建文件夾config,在新建flow.xml文件,配置要定義的流程

<?xml version="1.0" encoding="UTF-8"?>
<flow>
    <chain name="chain1">
        THEN(a, b, c)
    </chain>
</flow>

5.執(zhí)行

編排好的流程,在需要執(zhí)行的地方注入FlowExecutor,執(zhí)行execute2Resp

@Component
public class YourClass{
    
    @Resource
    private FlowExecutor flowExecutor;
    
    @Test
    public void testConfig(){
        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
    }
}

四、liteflow在實際中的應用

這里弱化背后的實際業(yè)務只展示作者在實際中的應用案例

1.添加依賴jar包

    <properties>
        <liteflow-spring.version>2.8.0</liteflow-spring.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.yomahub</groupId>
                <artifactId>liteflow-spring</artifactId>
                <version>${liteflow-spring.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

2.定義組件

定義組件和實現(xiàn)某些組件,注冊進上下文

@LiteflowComponent("checkRealNameAuthCmp")
@LiteflowCmpDefine
public class CheckRealNameAuthCmp {
    private static final Logger log = LoggerFactory.getLogger(CheckRealNameAuthCmp.class);
    @LiteflowMethod(LiteFlowMethodEnum.PROCESS)
    public void process(NodeComponent nodeComponent) throws Exception {
       // 獲取請求參數(shù)
       GeneratePolicyRightsParam generatePolicyRightsParam = nodeComponent.getSlot().getRequestData();
        // 如果pin為空則結束流程
       if (generatePolicyRightsParam == null || StringUtil.isEmpty(generatePolicyRightsParam.getUserPin())) {
                log.info("CheckRealNameAuthCmp -> process end, nodeComponent={},pin is null.", JsonUtil.toJSONString(nodeComponent));
                nodeComponent.setIsEnd(true);
            }
      //封裝設置流程編排上下文信息
      GenerateRightsContext generateRightsContext = nodeComponent.getContextBean(GenerateRightsContext.class);
            generateRightsContext.setGeneratePolicyRightsParam(generatePolicyRightsParam);
    }
}

LiteflowComponent:??普通組件 | LiteFlow

LiteflowCmpDefine:??聲明式組件 | LiteFlow

3.配置

添加對應的配置類及配置文件

Spring xml中的配置

spring-config.xml

 <import resource="classpath*:spring/spring-config-liteflow.xml"/>

spring-config-liteflow.xml

    <bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
    <bean id="springComponentScaner" class="com.yomahub.liteflow.spring.ComponentScanner"/>

    <!-- 注入liteflow的配置文件 -->
    <bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
        <property name="ruleSource" value="liteflow/flow.xml"/>
    </bean>

    <!-- 注入liteflow的執(zhí)行引擎 -->
    <bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
        <property name="liteflowConfig" ref="liteflowConfig"/>
    </bean>

    <!-- 注入liteflow的MonitorBus-->
    <bean class="com.yomahub.liteflow.monitor.MonitorBus">
        <constructor-arg ref="liteflowConfig"/>
        <property name="liteflowConfig" ref="liteflowConfig"/>
    </bean>

4.規(guī)則文件的定義

--流程的定義(第3步中l(wèi)iteflowConfig指定了規(guī)則文件為liteflow/flow.xml),所以需要在resources下新建文件夾liteflow,在新建flow.xml文件,配置要定義的流程

flow.xml

<?xml version="1.0" encoding="UTF-8"?>
<flow>
    <!-- liteflow流程編排:生成(發(fā)放)保單權益-->
    <chain name="sendPolicyRightsChain">
        <when value="checkRealNameAuthCmp"/>
        <then value="checkNewPolicyRightsCmp"/>
        <then value="getPolicyInfoCmp"/>
        <then value="policyMatchServiceRuleCmp"/>
        <then value="initPolicyRightsDataCmp"/>
        <then value="creatPlanGantRightsDataCmp"/>
        <then value="asyncFullFillCmp"/>
    </chain>
</flow>

5.執(zhí)行

執(zhí)行編排好的流程,在需要執(zhí)行的地方注入FlowExecutor,執(zhí)行execute2Resp

 @Resource
 private FlowExecutor flowExecutor;

public Boolean sendPolicyRights(GeneratePolicyRightsParam generatePolicyRightsParam) {
      //todo 入參和上下文不能混用,通用信息用map
      LiteflowResponse response = flowExecutor.execute2Resp("sendPolicyRightsChain", generatePolicyRightsParam, GenerateRightsContext.class,GenerateRightsContext.class);
                  
}

五、liteflow能力擴展(可視化)

liteflowt提供了流程編排的能力,只有研發(fā)人員能夠了解這內在的流程編排含義,對于其他產品或者業(yè)務并不能直觀的了解當前的業(yè)務流程,可視化并不友好。這時我們如何讓當前的流程可視化呢?編寫一個頁面直接讀取配置文件flow.xml進行顯示,這是沒有意義的。有意義的是我們能夠對組件進行可視化、對流程可視化、對流程編排可視化。

1、思想

提供新的jar包,獲取到業(yè)務系統(tǒng)聲名的組件、流程、顯示流程和組件、提供編排能力。

說明:

1、小工具jar包為可視化流程編排小工具,主要提供獲取業(yè)務系統(tǒng)聲明的組件、保存的流程、進行流程可視化展示、進行流程編排可視化等,使用liteflow-util標識區(qū)別于業(yè)務系統(tǒng)。

2、業(yè)務系統(tǒng)為組件聲明、流程執(zhí)行、業(yè)務邏輯系統(tǒng),使用liteflow-test標識

2、實現(xiàn)

2.1獲取特定的類或方法

如何從liteflow-util中獲取liteflow-test中聲明的組件

2.1.1獲取上下文環(huán)境

ApplicationContextAware

當一個bean的屬性初始化后會回調到setApplicationContext,從而設置應用上下文。

public interface ApplicationContextAware extends Aware {
	/**
	 * Set the ApplicationContext that this object runs in.
	 * Normally this call will be used to initialize the object.
	 * 

Invoked after population of normal bean properties but before an init callback such
	 * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
	 * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
	 * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
	 * {@link MessageSourceAware}, if applicable.
	 * @param applicationContext the ApplicationContext object to be used by this object
	 * @throws ApplicationContextException in case of context initialization errors
	 * @throws BeansException if thrown by application context methods
	 * @see org.springframework.beans.factory.BeanInitializationException
	 */
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

在liteflow-util中使用一個類來實現(xiàn)ApplicationContextAware,從而獲取到liteflow-test(依賴當前jar包的應用)的上下文環(huán)境

@Configuration
public class LiteFlowApplicationContext implements ApplicationContextAware {
   private static ApplicationContext controllerApplicationContext;
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      System.out.println("applicationContext = " + applicationContext);
      LiteFlowApplicationContext.controllerApplicationContext=applicationContext;
   }
   public static ApplicationContext getControllerApplicationContext() {
      return controllerApplicationContext;
   }
}
2.1.2從上下文獲取類

在liteflow-util中根據上下文環(huán)境獲取組件類這里的重點是Map<String, Object> mvcObjects = context.getBeansWithAnnotation(Service.class);

@Slf4j
public class ReferenceManager {
    private static Map<Class<?>, Object> interfaceMapRef = new ConcurrentHashMap<Class<?>, Object>();
    private static ReferenceManager instance;
    private ReferenceManager() {
    }
    public synchronized static ReferenceManager getInstance() {
        if (null != instance) {
            return instance;
        }
        instance = new ReferenceManager();
        ApplicationContext controllerContext = LiteFlowApplicationContext.getControllerApplicationContext();
        interfaceMapInit(controllerContext);
        return instance;
    }
    private static void interfaceMapInit(ApplicationContext context) {
        try {
            Map<String, Object> objects = Maps.newHashMapWithExpectedSize(64);
            //優(yōu)化 允許 ServiceBean 被MVC容器掃描
            Map<String, Object> mvcObjects = context.getBeansWithAnnotation(Service.class);
            objects.putAll(mvcObjects);
            if (objects == null || objects.size() == 0) {
                return;
            }
            for (Entry<String, Object> entry : objects.entrySet()) {
                /**
                 * 獲取代理對象的原對象
                 * 因為 jdk 動態(tài)代理通過接口
                 */
                Object objectImplProxy = entry.getValue();
                Object objectImpl = AopTargetUtils.getTarget(objectImplProxy);
                Class objectImplClass = objectImpl.getClass();
                if (objectImplClass.getInterfaces().length > 0) {
                    /**
                     * 規(guī)定 每個interface 只對應 一個實現(xiàn)類
                     * 如果 多個類實現(xiàn)了該接口 接口列表中只 顯示第一個實現(xiàn)類
                     */
                    Class interfaceClass = objectImplClass.getInterfaces()[0];
                    Object object = interfaceMapRef.get(interfaceClass);
                    if (object == null) {
                        interfaceMapRef.put(interfaceClass, objectImpl);
                    } else {
                    }
                } else {
                }
            }
        } catch (Exception e) {
        }
    }
    public Map<Class<?>, Object> getInterfaceMapRef() {
        return interfaceMapRef;
    }
}
@Component
public class ServiceScanner {
    public Set<Class<?>> classes() {
        return interfaceMapRef().keySet();
    }
    public Map<Class<?>, Object> interfaceMapRef() {
        return ReferenceManager.getInstance().getInterfaceMapRef();
    }
}
public class AopTargetUtils {
	/**
	 * 獲取 目標對象
	 * @param proxy 代理對象
	 * @return
	 * @throws Exception
	 */
	public static Object getTarget(Object proxy) throws Exception {

		if(!AopUtils.isAopProxy(proxy)) {
			return proxy;//不是代理對象
		}
		if(AopUtils.isJdkDynamicProxy(proxy)) {
			return getJdkDynamicProxyTargetObject(proxy);
		} else { //cglib
			return getCglibProxyTargetObject(proxy);
		}
	}
	private static Object getCglibProxyTargetObject(Object proxy) {
		try{
			Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
			h.setAccessible(true);
			Object dynamicAdvisedInterceptor = h.get(proxy);
			Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
			advised.setAccessible(true);
			Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
			return target;
		} catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	private static Object getJdkDynamicProxyTargetObject(Object proxy) {
		try{
			Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
			h.setAccessible(true);
			AopProxy aopProxy = (AopProxy) h.get(proxy);
			Field advised = aopProxy.getClass().getDeclaredField("advised");
			advised.setAccessible(true);
			Object target = ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();
			return target;
		} catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
}
2.2訪問liteflow-util頁面

如何在liteflow-test里訪問到liteflow-util包里的頁面并展示

(1)在liteflow-util內編寫一個Servlet類,直接繼承HttpServlet ,重寫doGet或者doPost方法

(2)在liteflow-util內將Servlet類配置到web.xml中

(3)在liteflow-util內準備前端的頁面(form表單、按鈕交互)

(4)在liteflow-test內引入依賴并啟動liteflow-test

2.2.1HttpServlet
public class HandServlet extends HttpServlet {
    private static final Logger log = LoggerFactory.getLogger(HandServlet.class);
    private String username = null;
    private String password = null;
    private ServletContext servletContext;
    public HandServlet() {
    }
    @Override
    public void init(ServletConfig config) {
        log.info("HandServlet->init,start");
        this.username = config.getInitParameter("loginUsername");
        this.password = config.getInitParameter("loginPassword");
        this.servletContext = config.getServletContext();
        log.info("HandServlet->init finish");
    }
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String contextPath = request.getContextPath();
        String servletPath = request.getServletPath();
        String requestURI = request.getRequestURI();
        response.setCharacterEncoding("utf-8");
        if (contextPath == null) {
            contextPath = "";
        }
        String uri = contextPath + servletPath;
        String path = requestURI.substring(contextPath.length() + servletPath.length());
        String usernameParam;
        if (!Objects.equals("/submitLogin", path)) {
            if (this.needLogin(request, path)) {
                this.redirect(request, response);
            } else {
                Result result;
                try {
                    result = this.requestHandler(path, request);
                } catch (Throwable var11) {
                    log.error("HandServlet->service,requestHandler error", var11);
                    result = Result.buildFail(var11.getMessage());
                }
                if (null != result) {
                    response.getWriter().print(JSON.toJSONString(result));
                } else {
                    this.returnResourceFile(path, uri, response);
                }
            }
        } else {
            usernameParam = request.getParameter("loginUsername");
            String passwordParam = request.getParameter("loginPassword");
            System.out.println("usernameParam = " + usernameParam);
            System.out.println("passwordParam = " + passwordParam);
//            if (this.username.equals(usernameParam) && this.password.equals(passwordParam)) {
            HttpSession session = request.getSession();
            session.setAttribute("lite-flow", this.username);
            session.setMaxInactiveInterval(300);
            response.getWriter().print(JSON.toJSONString(Result.buildSuccess("success")));
//            } else {
//                response.getWriter().print(JSON.toJSONString(Result.buildFail("用戶名或密碼錯誤")));
//            }
        }
    }
    private void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (request.getHeader("X-Requested-With") != null && "XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
            response.getWriter().print(JSON.toJSONString(Result.buildReLogin()));
        } else if (request.getHeader("Accept") != null && request.getHeader("Accept").contains("application/json")) {
            response.getWriter().print(JSON.toJSONString(Result.buildReLogin()));
        } else {
            response.sendRedirect("/lite-flow/login.html");
        }
    }
    private Result requestHandler(String path, HttpServletRequest request) {
        System.out.println("path = " + path);
        System.out.println("request = " + request);
        String initMenu = "/initMenu";
        String liteflow = "/liteflow";
        if (initMenu.equals(path)) {
            Map<String, Object> map = new HashMap(2);
            List<String> classObjectMap = getClassObjectMap();
            classObjectMap.forEach(item -> {
                int i = item.lastIndexOf(".");
                String substring = item.substring(i+1);
                System.out.println("substring = " + substring);
   LiteFlowNodeBuilder.createCommonNode().setId(substring).setName(substring).setClazz(item).build();
            });
            map.put("interfaceMapRef", classObjectMap);
            return Result.buildSuccess(map);
        } else if (liteflow.equals(path)) {
            try {
                try {
                    String postData = this.getPostData(request);
                    log.info("HandServlet -> requestHandler start, postData={}", postData);
                    JSONObject jsonObject = JSONObject.parseObject(postData);
                    JSONArray checkList = jsonObject.getJSONArray("checkList");
                    String chainId = (String) jsonObject.get("chainId");
                    log.info("HandServlet -> requestHandler start, path={},checkList={}", path, checkList);
                    ArrayList arrayList = new ArrayList();
                    checkList.forEach(item -> {
                        String itemStr = (String) item;
                        int i = itemStr.lastIndexOf(".");
                        String substring = itemStr.substring(i+1);
                        arrayList.add(substring);
                    });
                    String str = StringUtils.join(arrayList, ",");
                    log.info("HandServlet -> requestHandler start, str={}", str);
//                    String elss = "THEN(" + str + ")";
//                    log.info("HandServlet -> requestHandler start, elss={}", elss);
                    Condition condition = LiteFlowConditionBuilder.createCondition(ConditionTypeEnum.TYPE_THEN).setValue(str).build();
                    log.info("HandServlet -> requestHandler start, condition={}", condition);
                    LiteFlowChainBuilder.createChain().setChainName(chainId).setCondition(condition).build();
                } catch (Throwable var3) {
                    log.error("HandServlet -> requestHandler exception 未知異常, var3={}", var3);
                }
            } catch (Throwable var3) {
                log.info("MqUtil->haveProducer,error", var3);
            }
            return Result.buildSuccess(false);
        } else {
            return null;
        }
    }

    public String getPostData(HttpServletRequest request) {
        StringBuilder data = new StringBuilder();
        String line;
        BufferedReader reader;
        try {
            reader = request.getReader();
            while (null != (line = reader.readLine())) {
                data.append(line);
            }
        } catch (IOException e) {
            return null;
        }
        return data.toString();
    }

    private List<String> getClassObjectMap() {
        List<String> result = new ArrayList<>();
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        Map<String, ServiceScanner> serviceScannerMap = webApplicationContext.getBeansOfType(ServiceScanner.class);
        ServiceScanner serviceScanner = serviceScannerMap.get("serviceScanner");
        Map<Class<?>, Object> interfaceMapRef = serviceScanner.interfaceMapRef();
        if (null != interfaceMapRef) {
            //排序 所有接口
            List<Map.Entry<Class<?>, Object>> arrayList = new ArrayList<Map.Entry<Class<?>, Object>>(interfaceMapRef.entrySet());
            Collections.sort(arrayList, new Comparator<Map.Entry<Class<?>, Object>>() {
                @Override
                public int compare(Map.Entry<Class<?>, Object> o1, Map.Entry<Class<?>, Object> o2) {
                    return o1.getKey().getSimpleName().compareTo(o2.getKey().getSimpleName());
                }
            });
            //遍歷 所有接口
            for (Map.Entry<Class<?>, Object> entry : arrayList) {
                String className = entry.getValue().getClass().getName();
                System.out.println("class = " + className);
                result.add(className);
//                List<Method> interfaceMethodList = Arrays.asList(entry.getKey().getDeclaredMethods());
//                //方法列表排序
//                Collections.sort(interfaceMethodList, new Comparator<Method>() {
//                    @Override
//                    public int compare(Method o1, Method o2) {
//                        return o1.getName().compareTo(o2.getName());
//                    }
//                });
//                for (Method method : interfaceMethodList) {
//                    System.out.println("method = " + method);
//                    System.out.println("methodName = " + method.getName());
//                    System.out.println("methodParameterTypes = " + method.getParameterTypes());
//                    System.out.println("methodReturn = " + method.getReturnType());
//                }
            }

        }
        System.out.println("result = " + result);
        return result;
    }
    private boolean needLogin(HttpServletRequest request, String path) {
        return this.isRequireAuth() && !this.alreadyLogin(request) && !this.checkLoginParam(request) && !"/login.html".equals(path) && !path.startsWith("/css") && !path.startsWith("/js") && !path.startsWith("/img");
    }
    private boolean checkLoginParam(HttpServletRequest request) {
        String usernameParam = request.getParameter("loginUsername");
        String passwordParam = request.getParameter("loginPassword");
        if (null != this.username && null != this.password) {
            return this.username.equals(usernameParam) && this.password.equals(passwordParam);
        } else {
            return false;
        }
    }
    private boolean isRequireAuth() {
        return this.username != null;
    }
    private boolean alreadyLogin(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        return session != null && session.getAttribute("lite-flow") != null;
    }
    private void returnResourceFile(String fileName, String uri, HttpServletResponse response) throws IOException {
        String filePath = this.getFilePath(fileName);
        if (filePath.endsWith(".html")) {
            response.setContentType("text/html; charset=utf-8");
        }
        if (fileName.endsWith(".jpg")) {
            byte[] bytes = Utils.readByteArrayFromResource(filePath);
            if (bytes != null) {
                response.getOutputStream().write(bytes);
            }
        } else {
            String text = Utils.readFromResource(filePath);
            if (text == null) {
                response.sendRedirect(uri + "/login.html");
            } else {
                if (fileName.endsWith(".css")) {
                    response.setContentType("text/css;charset=utf-8");
                } else if (fileName.endsWith(".js")) {
                    response.setContentType("text/javascript;charset=utf-8");
                }

                response.getWriter().write(text);
            }
        }
    }
    private String getFilePath(String fileName) {
        return "view" + fileName;
    }
2.2.2配置web.xml

在liteflow-util內web.xml配置自定義的servlet文章來源地址http://www.zghlxwxcb.cn/news/detail-829221.html

    <servlet>
        <servlet-name>handOfLite</servlet-name>
        <servlet-class>com.xx.utils.liteflow.handler.HandServlet</servlet-class>
        <init-param>
            <param-name>loginUsername</param-name>
            <param-value>Username</param-value>
        </init-param>
        <init-param>
            <param-name>loginPassword</param-name>
            <param-value>Password</param-value>
        </init-param>
        <load-on-startup>5</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>handOfLite</servlet-name>
        <url-pattern>/hand-of-lite/*</url-pattern>
    </servlet-mapping>
2.2.3頁面準備

到了這里,關于Unity UGUI的Physi會隨機改變csRaycaster (物理射線檢測)組件的介紹及使用的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Unity UGUI的PhysicsRaycaster (物算法能力可視化理射線檢測)組件的介紹及使用

    Outline(描邊)組件是Unity UGUI中的一種特效組件,用于給UI元素添加描邊效果。通過設置描邊的顏色、寬度和模糊程度,可以使UI元素在視覺上更加突出。 Outline(描邊)組件通過在UI元素周圍繪制多個相同的UI元素,并設置不同的顏色和大小,從而實現(xiàn)描邊的效果。描邊的寬度和模糊

    2024年02月07日
    瀏覽(21)
  • Unity UG算法能力可視化UI的PhysicsRaycaster (物理射線檢測)組件的介紹及使用

    PhysicsRaycaster是Unity UGUI中的一個組件,用于在UI元素上進行物理射線檢測。它可以檢測鼠標或觸摸事件是否發(fā)生在UI元素上,并將事件傳遞給相應的UI元素。 PhysicsRaycaster通過發(fā)射一條射線來檢測UI元素。當射線與UI元素相交時,PhysicsRaycaster會將事件傳遞給相應的UI元素。 Event

    2024年01月20日
    瀏覽(50)
  • 10.Unity2D 橫版 簡單AI 之 敵人隨機移動+自動巡邏+障礙物跳躍+懸崖處轉身+射線檢測

    10.Unity2D 橫版 簡單AI 之 敵人隨機移動+自動巡邏+障礙物跳躍+懸崖處轉身+射線檢測

    總目錄 9.Unity2D 簡單AI 之 敵人跳躍條件優(yōu)化+自動范圍內檢測敵人發(fā)起攻擊(索敵)+對象池優(yōu)化+主角受傷死亡_ζ?? ??霧 ??狼 ???的博客-CSDN博客 Unity2D 簡單AI 之 敵人跳躍條件優(yōu)化+自動范圍內檢測敵人攻擊+敵人二連擊。在敵人預制體下,創(chuàng)建空物體EnemyCanAttack,改成不

    2023年04月20日
    瀏覽(61)
  • Unity UGUI的PhysicsRaycaster (物理射相當于利用泛型函數(shù)保存了類型信息線檢測)組件的介紹及使用

    這是在Datadog公司任職的Kevin Gosse大佬使用C#編寫.NET分析器的系列文章之一,在國內只有很少很少的人了解和研究.NET分析器,它常被用于APM(應用性能診斷)、IDE、診斷工具中,比如Datadog的APM,Visual Studio的分析器以及Rider和Reshaper等等。之前只能使用C++編寫,自從.NET NativeAOT發(fā)

    2024年01月22日
    瀏覽(27)
  • Unity  SteamVR 2.x  UGUI射線交互 +物品射線點擊+物品抓起(超級簡單)

    Unity SteamVR 2.x UGUI射線交互 +物品射線點擊+物品抓起(超級簡單)

    剛開始先查看了其他道友的方案:1.Unity使用SteamVR2.0實現(xiàn)基本功能(瞬移,抓取物品,射線點擊,UI交互等)_貪小心的博客-CSDN博客_unity steam vr 2.【Steam VR 2.0】5.射線操作UGUI-射線點擊物體_恩博同學的博客-CSDN博客_htc steamvr 射線點擊ui 嗯。。。試著嘗試了一下,不是很好用,于是乎記

    2023年04月25日
    瀏覽(23)
  • Unity UGUI的GraphicRaycaster(射線投射)組件的介紹及使用

    GraphicRaycaster是Unity UGUI系統(tǒng)中的一個組件,用于處理射線投射事件。它可以將射線投射到UI元素上,并檢測是否有UI元素被點擊或觸摸到。 GraphicRaycaster通過射線投射的方式來檢測UI元素的點擊事件。當用戶點擊屏幕或觸摸屏幕時,GraphicRaycaster會發(fā)射一條射線,然后檢測射線是

    2024年02月15日
    瀏覽(97)
  • unity-2D游戲地面檢測 三射線檢測

    unity-2D游戲地面檢測 三射線檢測

    ? ? 2D游戲中跳躍是不可或缺的功能,要實現(xiàn)跳躍功能,就必須進行地面檢測!常規(guī)方法是使用一根往角色下方延伸的射線檢測,但是這種方法在一些復雜不規(guī)則的地面效果通常不盡人意。通過增加射線數(shù)量,即可完善這種方法的不足,達到在復雜地面也能正確檢測角色是否

    2024年02月15日
    瀏覽(22)
  • Unity 的射線檢測

    Unity 的射線檢測

    Unity版本2020.3.32f1c1 目錄 Ray RaycastHit Physics.Raycast() RaycastHit[] ??Layer 應用 1.對Bad層級的物體進行著色 2.從相機發(fā)射射線與地面進行射線交互 3.運動的物體在場景中進行避障 總結 參考資料 原理是發(fā)射一條射線,傳入起始點和起始方向當做射線的起點和方向。 在OnDrawGizmos()函數(shù)中

    2024年02月07日
    瀏覽(24)
  • Unity 射線檢測

    Unity 射線檢測

    在Unity中,射線檢測(Raycasting)是一種常用的技術,用于檢測射線是否與場景中的物體相交。這在游戲開發(fā)中用于實現(xiàn)點擊物體、射線武器的碰撞檢測、角色與環(huán)境的交互等方面非常有用。 定義:表示從一個點沿著特定方向延伸的虛擬線段 屬性: direction 射線的方向。 orig

    2024年02月13日
    瀏覽(21)
  • Unity之射線檢測

    Unity之射線檢測

    目錄 ??一、射線檢測原理 ??1.2、實現(xiàn)實例? ??二、導航 ??2.1 導航網格的使用 ??2.2 創(chuàng)建角色,在地形上移動 ??2.3 動態(tài)障礙物? ??2.4 網格鏈接? ??2.5 自定義網格鏈接? ??2.6 區(qū)域 不知道大家有沒有玩過紅色警戒?—— 一款即時戰(zhàn)略游戲,和罪惡都市一樣小編小學的時

    2024年01月20日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包