java框架-struts2

news2024/9/22 23:22:56

文章目录

  • 1. struts2访问流程&架构&介绍
  • 2. 搭建struts2框架
  • 3. strust.xml配置详解
  • 4. Action生命周期
  • 5. ActionContext内容
  • 6. 访问servletAPI方式
  • 7. jsp获得
  • 8. Action接收参数
  • 9. struts、hibernate的javassist-3.18.1-GA.jar包重复,删除版本低的.
  • 10. OGNL表达式
    • 10.1. OGNL与Struts2的结合原理
    • 10.2. struts2与ognl结合体现
  • 11. 自定义拦截器
  • 12. struts2标签(了解)
  • 13. 表现层抽取
  • 14. 文件上传
  • 15. 处理Ajax请求
  • 总结


1. struts2访问流程&架构&介绍

  • 自动封装参数、参数校验、结果的处理(转发|重定向)、国际化、显示等待页面、表单的防止重复提交
  • struts2前身:webwork框架(基于filter)与struts1(基于Servlet)两者无关.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 搭建struts2框架

导包:web-content -->web-INF-->lib
asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
commons-fileupload-1.3.1.jar
commons-io-2.2.jar
commons-lang3-3.2.jar
freemarker-2.3.22.jar
javassist-3.11.0.GA.jar
log4j-api-2.2.jar
log4j-core-2.2.jar
ognl-3.0.6.jar
struts2-core-2.3.24.jar
xwork-core-2.3.24.jar

在src下面创建*Action.java
	方法一:创建一个类.不继承任何父类.不实现任何接口.使struts2框架的代码侵入性更低.
	public class DemoAction {
		public String hello(){
			return "success";
		}
	}
	方法二:实现一个接口Action
	import com.opensymphony.xwork2.Action;
	// 里面有execute方法,提供action方法的规范.
	// Action接口预置了一些字符串.可以在返回结果时使用.为了方便
	public class DemoAction implements Action {
		@Override
		public String execute() throws Exception {
			return null;
		}
	}
	方法三:继承ActionSupport
	// 帮我们实现了 Validateable, ValidationAware, TextProvider, LocaleProvider .
	//如果我们需要用到这些接口的实现时,不需要自己来实现了.
	public class Demo5Action  extends ActionSupport{}

创建struts主配置文件在src下创建struts.xml
导入约束window菜单--> preference-->cata 在web App Libraries--struts2-core-2.3.24.jar--struts-2.3.dtd
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
		<!-- package:将Action配置封装.就是可以在Package中配置很多action.
			name属性: 给包起个名字,起到标识作用.随便起.不能其他包名重复.
			namespace属性:给action的访问路径中定义一个命名空间
			extends属性: 继承一个 指定包
			abstract属性:包是否为抽象的; 标识性属性.标识该包不能独立运行.专门被继承 -->
	<package name="hello" namespace="/hello" extends="struts-default">
			<!-- action元素:配置action类
				name属性: 决定了Action访问资源名.
				class属性: action的完整类名
				method属性: 指定调用Action中的哪个方法来处理请求 -->
		<action name="TestAction" class="com.junye.test.HelloAction" method="fun">
			<!-- result元素:结果配置 
				name属性: 标识结果处理的名称.与action方法的返回值对应.
				type属性: 指定调用哪一个result类来处理结果,默认使用转发.
				标签体:填写页面的相对路径-->
			<result name="success">/hello.jsp</result>
		</action>
	</package>
	<!-- 引入其他struts配置文件 -->
	<include file="cn/junye/b_dynamic/struts.xml"></include>
</struts>

将struts2核心过滤器配置到web.xml,配置在欢迎页前面
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
测试:访问http://localhost:8080/mystruts/hello/TestAction

3. strust.xml配置详解

  • struts2常量配置方式(先后也是加载顺序)后加载覆盖
方式1:src/struts.xml(只用这个)
	<constant name="struts.i18n.encoding" value="UTF8"></constant>
方式2:在src下创建struts.properties:
struts.i18n.encoding=UTF8
方式3:在项目的web.xml中
<context-param>
	<param-name>struts.i18n.encoding</param-name>
	<param-value>UTF-8</param-value>
</context-param>
  • struts2常量配置位置App Libraries–struts2-core-2.3.24.jar–org.apache.struts2-default.properties;
<!--常量配置struts.xml-->
<!-- i18n:国际化. 解决post提交乱码 get提交,按以前的方式-->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- 指定访问action时的后缀名 
http://localhost:8080/struts2_day01/hello/HelloAction.?默认.action 和 “空”-->
<constant name="struts.action.extension" value="?"></constant>
<!-- 指定struts2是否以开发模式运行1.热加载主配置.(不需要重启即可生效)2.提供更多错误信息输出,方便开发时的调试-->
<constant name="struts.devMode" value="true"></constant>
  • struts2动态方法调用(struts.xml)
通配符方式  使用{1} 取出第一个星号通配的内容
<package name="dynamic" namespace="/dynamic" extends="struts-default" >
	<action name="Demo1Action_*" class="cn.b.Demo1Action" method="{1}" >
		<result name="success" >/{1}.jsp</result>
	</action>
</package>	
访问http://localhost:8080/struts2_day01/dynamic/Demo1Action_find.action跳转到find.jsp
  • struts2中的默认配置
<package name="default" namespace="/default" extends="struts-default" >
	<!--不声明则默认访问,不管整合没整合-->
	<!--<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />-->
	<!-- 声明后找不到包下的action,会使用Demo2Action作为默认action处理请求 -->
	<default-action-ref name="Demo2Action"></default-action-ref>
	<!-- method属性:execute result的name属性:success   result的type属性:dispatcher转发  -->
	<!-- class属性:com.opensymphony.xwork2.ActionSupport -->
	<action name="Demo2Action"   >
		<result  >/hello.jsp</result>
	</action>
</package>
http://localhost:8080/struts2_day01/default/xxxx.action,默认访问Demo2Action
  • 结果跳转方式struts.xml中(result的type属性)用于post/get提交
	转发
	<action name="Demo1Action" class="cn.a_result.Demo1Action" method="execute" >
		<result name="success" type="dispatcher" >/hello.jsp</result>
	</action>

	重定向地址栏发生变化
	<action name="Demo2Action" class="cn.a_result.Demo2Action" method="execute" >
		<result name="success" type="redirect" >/hello.jsp</result>
	</action>

	转发到Action
	<action name="Demo3Action" class="cn.a_result.Demo3Action" method="execute" >
		<result name="success" type="chain">
			<param name="actionName">Demo1Action</param>
			<param name="namespace">/</param>//转发的命名空间
		</result>
	</action>

	重定向到Action
	<action name="Demo4Action" class="cn.a_result.Demo4Action" method="execute" >
		<result  name="success"  type="redirectAction">
			<param name="actionName">Demo1Action</param>
			<param name="namespace">/</param>//转发的命名空间
		</result>
	</action>
  • 全局结果集
<global-result>
	<result name="" type="redirect">/login.jsp</result>
</global-result>
<global-exception-mappings>
	<exception-mapping result="error" exception="java.lang.RuntimeException">
</exception-mapping>
</global-exception-mappings>

4. Action生命周期

  • 1.每次请求到来时,都会创建一个新的Action实例、
  • 2.Action是线程安全的.可以使用成员变量接收参数,servlet线程不安全

5. ActionContext内容

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • attr域以最小的域的map的键为准、request域就是request中的一个map

6. 访问servletAPI方式

通过ActionContext,通过Map原来的方法键值对获得,或者通过封装好的方法获得
//request域=> map (不推荐,ActionContext生命周期和request一样,推荐ActionContext)
//不推荐Map<String, Object> requestScope = (Map<String, Object>) ActionContext.getContext().get("request");
ActionContext.getContext().put("name", "requestTom");//推荐

//session域 => map
Map<String, Object> sessionScope = ActionContext.getContext().getSession();
sessionScope.put("name", "sessionTom");
销毁session:ActionContext.getContext().getSession().invalidate();

//application域=>map
Map<String, Object>applicationScope =ActionContext.getContext().getApplication(); 
操作map put("name","Tom")、remove("name", "Tom")、get("","");

//获得原生response的方法(推荐)
HttpServletResponse response = ServletActionContext.getResponse();
	
通过ServletActionContext(不推荐)获得各种原生域
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
HttpServletResponse response = ServletActionContext.getResponse();
ServletContext servletContext = ServletActionContext.getServletContext();
PageContext pageContext = ServletActionContext.getPageContext();
操作各种域:setAttribute、addAttribute、getAttribute、removeAttribute
通过实现接口方式(用拦截器完成的)
public class Demo7Action extends ActionSupport implements ServletRequestAware {
	private HttpServletRequest request;
	public String execute() throws Exception { 	
		System.out.println("原生request:"+request);
		return SUCCESS;
	}
	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}	
}

7. jsp获得

page:${pageScope.name};
request: ${requestScope.name}
session:${sessionScope.name}
application:${applicationScope.name}
${name}按顺序取

8. Action接收参数

表单
<form action="${pageContext.request.contextPath}/Demo8Action">
	用户名:<input type="text" name="name" /><br>
	年龄:<input type="text" name="age" /><br>
	生日:<input type="text" name="birthday" /><br>
		<input type="submit" value="提交" />
</form>
单个类型:能获得radio和chekbox的值
属性驱动获得参数:set/get方法
public class Demo8Action extends ActionSupport  {
	//准备与参数键名称相同的属性
	private String name;
	//自动类型转换 只能转换8大基本数据类型以及对应包装类
	private Integer age;
	//支持特定类型字符串转换为Date ,例如 yyyy-MM-dd,一定要有set/get方法
	private Date   birthday;
	public String execute() throws Exception { 
		System.out.println("name参数值:"+name+",age参数值:"+age+",生日:"+birthday);
		return SUCCESS;
	}
}
对象驱动获得参数
public class Demo9Action extends ActionSupport  {
	private User user;//生成set/get方法
	public String execute() throws Exception { 	
		System.out.println(user);
		return SUCCESS;
	}
}
模型驱动获得参数实现接口(只能返回一个对象)
public class Demo10Action extends ActionSupport implements ModelDriven<User> {
	private User user =new User();
	public String execute() throws Exception { 
		System.out.println(user);
		return SUCCESS;
	}
	@Override
	public User getModel() {
		return user;
	}
}
	④radio或checkbox的获取
	只要将属性名字设置成对应的radio或checkbox的值即可获得提交的参数,
	radio是单个值,而checkbox是一行value,空格value的结构,拆分即可
	String[] split = hobby.split(", ");
	for(String s:split) {
		System.err.println(s);
	}
	⑤集合类型参数封装
	list:<input type="text" name="list" /><br>//不指定索引则一个一个塞
	list:<input type="text" name="list[3]" /><br>//指定就放到规定的地方,不指定就null
	private List<String> list;set、get方法
	map:<input type="text" name="map['haha']" /><br>//值封装到键值haha上
	private Map<String,String> map;set/get方法

9. struts、hibernate的javassist-3.18.1-GA.jar包重复,删除版本低的.

10. OGNL表达式

Ognl.png

  • OGNL:对象视图导航语言. ${user.addr.name} 这种写法就叫对象视图导航.
  • OGNL不仅仅可以视图导航.支持比EL表达式(11内置对象)更加丰富的功能.
	使用OGNL准备工作:struts2 的包中已经包含了ognl-3.0.6.jar.不需要导入额外的jar包
	保存
	root和context可以放多个对象或者map,查找时只输入key或者属性名即可。从栈顶一直查到栈低,重复的查不到两个
	User rootUser = new User("tom",18);
	Map<String,User> context = new HashMap<String,User>();
	context.put("user1", new User("jack",18));
	context.put("user2", new User("rose",22));
	OgnlContext oc = new OgnlContext();
	oc.setRoot(rootUser);//将rootUser作为root部分
	oc.setValues(context);//将context这个Map作为Context部分

	基本取值
	//取出root中user对象的name属性
	String name = (String) Ognl.getValue("name", oc, oc.getRoot());
	Integer age = (Integer) Ognl.getValue("age", oc, oc.getRoot());
	//取出context中键为user1对象的name属性#代表context
	String name = (String) Ognl.getValue("#user1.name", oc, oc.getRoot());
	String name2 = (String) Ognl.getValue("#user2.name", oc, oc.getRoot());
	Integer age = (Integer) Ognl.getValue("#user2.age", oc, oc.getRoot());

	赋值
	//将root中的user对象的name属性赋值
	Ognl.getValue("name='jerry'", oc, oc.getRoot());
	String name2 = (String) Ognl.getValue("#user1.name='a',#user1.name", oc, oc.getRoot());

	调用方法(赋值和取值)
	//调用root中user对象的setName方法
	Ognl.getValue("setName('lilei')", oc, oc.getRoot());
	String name = (String) Ognl.getValue("getName()", oc, oc.getRoot());
	String name2 = (String)Ognl.getValue("#user1.setName('lucy'),#user1.getName()", oc, oc.getRoot());

	调用静态方法(static)
	String name = (String) Ognl.getValue("@cn.a_ognl.HahaUtils@echo('hello 强勇!')", oc, oc.getRoot());//@完整类名
	//Double pi = (Double) Ognl.getValue("@java.lang.Math@PI", oc, oc.getRoot());
	Double pi = (Double) Ognl.getValue("@@PI", oc, oc.getRoot())

	创建对象(List,Map)
	Integer size = (Integer) Ognl.getValue("{'tom','jerry','jack','rose'}.size()", oc, oc.getRoot());
	String name = (String) Ognl.getValue("{'tom','jerry','jack','rose'}[0]", oc, oc.getRoot());//tom
	String name2 = (String) Ognl.getValue("{'tom','jerry','jack','rose'}.get(1)", oc, oc.getRoot());//jerry
	Integer size2 = (Integer) Ognl.getValue("#{'name':'tom','age':18}.size()", oc, oc.getRoot());
	String name3  = (String) Ognl.getValue("#{'name':'tom','age':18}['name']", oc, oc.getRoot());
	Integer age  = (Integer) Ognl.getValue("#{'name':'tom','age':18}.get('age')", oc, oc.getRoot());

10.1. OGNL与Struts2的结合原理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

	接口ValueStack实现类OgnlValueStack包括root和context两部分
	public class OgnlValueStack implements ValueStack{
		CompoundRoot root;//栈结构
		transient Map<String,Object> context;//map结构
	}

	//root是栈,是由ArrayList和栈方法模拟的,访问栈中属性的特点.由上到下
	//默认情况下,root放置的是被访问的当前Aciton,请求参数被封装到Action中
	public class CompoundRoot extends ArrayList{
		//栈方法:弹栈
		public Object pop(){
			return remove(0);
		}
		//栈方法:压栈
		public Object push(Object o){
			add(0,o);
		}
	}
	查看值栈中两部分内容
	(使用DEBUG标签)<s:debug></s:debug>

10.2. struts2与ognl结合体现

  • 参数接收

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 获得ValueStack和ActionContext的方法

    • 获得ActionContext数据中心: ActionContext.getContext();
    • 获得值栈:ActionContext.getContext().getValueStack();
  • ValueStack的API(少用)常用来接收表单数据,很少往这root放数据

    • 将数据obj放入值栈ValueStack中的Root:ActionContext.getContext().getValueStack().push(obj);
    • 从值栈ValueStack中的Root将数据obj取出:ActionContext.getContext().getValueStack().pop();
    • 从值栈ValueStack中的Root将查询数据Object findValue = ActionContext.getContext().getValueStack().findValue(“name”);
    • 从值栈ValueStack中的Root将修改数据ActionContext.getContext().getValueStack().setParameter(“name”, “name”);
    • 通过键值对key和value将数据放入值栈ValueStack中的Context:ActionContext.getContext().put(key, value);
    • 通过键名找到值栈ValueStack中的对象Object object = ActionContext.getContext().get(“name”);
    • 可以通过EL表达式${}从值栈中的Context取数据
<action name="Demo4Action" class="cn.a_result.Demo4Action" method="execute" >
	<result  name="success"  type="redirectAction">
		<param name="actionName">Demo1Action</param>
		<param name="namespace">/</param>//转发的命名空间
		<param name="name">{{name}}</param>//转发的命名空间
	</result>
</action>
语法:${ognl表达式},将数据传递到结果那边,不过一般都是在域中传递,不常用
可以通过EL表达式${}从值栈中的Context取数据

扩展:request对象的getAttribute方法
同时也是ognl表达式获得参数的方法(查找顺序)
request.getAttribute()
原生request域
查找valueStack的Root部分(栈)
查找valueStack的context部分(ActionContext)

11. 自定义拦截器

//拦截器生命周期:随项目的启动而创建,随项目关闭而销毁
①拦截器创建
方法一:实现Interceptor接口并实现其三个方法
public class MyInterceptor implements Intercepter{}

方法二:继承AbstractInterceptor
空实现了init 和 destory方法. 我们如果不需要实现这两个方法,就可以只实现intercept方法
public class MyInterceptor2 extends AbstractInterceptor {}

方法三:继承MethodFilterInterceptor 方法过滤拦截器并复写doIntercept方法
//功能: 定制拦截器拦截的方法.  定制哪些方法需要拦截、哪些方法不需要拦截
public class MyInterceptor3 extends MethodFilterInterceptor{
	doIntercept(ActionInvocation invocation){
		放行+前后处理:
		//前处理
		invocation.invoke();
		//后处理
		//不处理直接放行
		return invocation.invoke();
		不放行,直接跳转到一个结果页面
		return "success";//不执行后续的拦截器以及Action,直接交给Result处理结果.进行页面跳转
	}
}

②配置struts.xml,在default.properties中可以找到相应的默认配置
注册拦截器<interceptor name="" class=""></interceptor>

定制拦截方法并配置拦截器栈
<interceptor-stack name="myStack">
	<!-- 自定义拦截器引入(建议放在20个拦截器之前) -->
	<interceptor-ref name="myInter3">
		<!-- 指定哪些方法不拦截
		<param name="excludeMethods">add,delete</param> -->
		<!-- 指定哪些方法需要拦截 -->
		<param name="includeMethods">add,delete</param>
	</interceptor-ref>
	<!-- 引用默认的拦截器栈(20个) -->
	<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>

指定包中默认拦截器栈<default-interceptor-ref name="myStack"></default-interceptor-ref>

Action指定拦截器
<action name="Demo1Action_*" class="cn.interceptor.Demo1Action" method="{1}" >
	<!-- 为Action单独指定走哪个拦截器(栈) 
	<interceptor-ref name="myStack"></interceptor-ref>-->
	<result name="success" type="dispatcher" >/index.jsp</result>
</action>

12. struts2标签(了解)

	控制标签
	遍历标签 iterator 
	<s:iterator value="#list" >
		<s:property /><br>
	</s:iterator>

	<s:iterator value="#list" var="name" >
		<s:property value="#name" /><br>
	</s:iterator>

	<s:iterator begin="1" end="100" step="1"  >
		<s:property />
	</s:iterator>

	if标签
	<s:if test="#list.size()==4">
		list长度为4!
	</s:if>
	<s:elseif test="#list.size()==3">
		list长度为3!
	</s:elseif>
	<s:else>
		list不3不4!
	</s:else>
	判断boolean值不要自己用==true判断

	数据标签
	<!--property 配合ognl表达式页面取值,Action没有返回数据时没有值-->
	<s:property value="#list.size()" />
	<!--获得session中的值,常用于表达登录用户信息-->
	<s:property value="#session.user.name" />

	表单标签
	<!-- 好处1: 内置了一套样式.  - 好处2: 自动回显,根据栈中的属性  -->
	<!-- theme:指定表单的主题,就是表单的style,xhtml:默认,simple:没有主题-->
	<s:form action="Demo3Action" namespace="/" theme="xhtml" >
		<s:textfield name="name" label="用户名"  ></s:textfield>
		<s:password name="password" label="密码" ></s:password>
		<s:radio list="{'男','女'}" name="gender" label="性别" ></s:radio>
		<s:radio list="#{1:'男',0:'女'}" name="gender" label="性别" ></s:radio>
		<s:checkboxlist list="#{2:'抽烟',1:'喝酒',0:'烫头'}" name="habits" label="爱好" ></s:checkboxlist>
		<s:select list="#{2:'大专',1:'本科',0:'硕士'}" headerKey="" headerValue="---请选择---" name="edu" label="学历" ></s:select>
		<s:file name="photo" label="近照" ></s:file>
		<s:textarea name="desc" label="个人简介" ></s:textarea>
		<s:submit value="提交" ></s:submit>
	</s:form>

	非表单标签
	在action中添加错误信息this.addActionError("你错了");
	取出错误信息<s:actionerror>
	<s:debug></s:debug>

13. 表现层抽取

	//表现层通用实现
	public class BaseAction<T> extends ActionSupport implements ModelDriven<T> {
		//模型对象
		private T model;
		public T getModel() {
			return model;
		}
		
		//在构造方法中动态获取实体类型,通过反射创建model对象
		public BaseAction() {
			ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
			//获得BaseAction上声明的泛型数组
			Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
			Class<T> entityClass = (Class<T>) actualTypeArguments[0];
			//通过反射创建对象
			try {
				model = entityClass.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
	}

14. 文件上传

	<!-- 文件上传页面三个要求:
	表单必须post提交,
	表单提交类型,必须多项式,
	文件上传使用<input type="file"/>组件 -->
	<FORM id=form1 name=form1
	action="${pageContext.request.contextPath }/CustomerAction_add"
	method="post" enctype="multipart/form-data">
	<input type="file" name="photo"/>
	</FORM>
	//上传的文件自动封装到File对象,
	//只需后台提供一个FIle属性且名字与前台file的name属性名相同的字段
	private File photo;
	//在提交键名后加上固定后缀FIleName,文件名会自动封装到属性中
	private String photoFileName;
	//在提交键名后加上固定后缀ContentType,文件MIME类型会自动封装到属性中
	//image/jpeg等
	private String photoContentType;
	set/get方法

	//测试上传,上传文件保存到指定位置
	//默认保存到?
	photo.renameTo(new File("F:/testupload/test.jpg"));

15. 处理Ajax请求

public String fun(){
	通过ServletAPI方式		
	/*使用jsonlib将pageBean转为json,通过输出流写回页面中 
	JSONObject将单一对象转为json,不用看里面是什么,主要看本来的性质
	JSONArray将数组或者集合对象转为json*/
	JsonConfig jsonConfig = new JsonConfig();
	jsonConfig.setExcludes(new String[] {"currentPage","detachedCriteria","pageSize"});
	String json = JSONObject.fromObject(pageBean).toString();

	//ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");
	ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
	ServletActionContext.getResponse().getWriter().print(f);
	return null;
}

总结

本文介绍了的struts2使用,如有问题欢迎私信和评论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1925072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity中一键生成具有身体感知的虚拟人物动作

在虚拟现实(VR)和增强现实(AR)的浪潮中&#xff0c;如何让虚拟人物的动作更加自然、真实&#xff0c;已经成为一个重要课题。AI4Animation项目&#xff0c;一个由 Sebastian Starke 主导的开源框架&#xff0c;为Unity开发者提供了强大的工具集&#xff0c;以实现这一目标。本文…

唐刘:当 SaaS 爱上 TiDB(一)- 行业挑战与 TiDB 的应对之道

导读 在 TiDB 8.1 发布后&#xff0c;TiDB 展现了强大的支持 SaaS 业务的能力&#xff0c;成为 SaaS 业务数据库的优先选择之一。 本文为“当 SaaS 爱上 TiDB”系列文章的第一篇&#xff0c;系列文章将从技术原理和真实用户体验两个角度深入探讨 TiDB 在 SaaS 业务中的表现&a…

idm站点抓取可以用来做什么 idm站点抓取能抓取本地网页吗 idm站点抓取怎么用 网络下载加速器

在下载工具众多且竞争激烈的市场中&#xff0c;Internet Download Manager&#xff08;简称IDM&#xff09;作为一款专业的下载加速软件&#xff0c;仍然能够赢得众多用户的青睐&#xff0c;这都要得益于它的强大的下载功能。我们在开始使用IDM的时候总是有很多疑问&#xff0c…

Mysql具体数据操作和表的约束(上)

表中数据的增删改查 插入数据(添加数据) 1.按指定字段插入数据:insert into <表名> (字段1,字段2,...) values (),(),.... 注意1:values后面的括号是指行数(几条记录),一个括号表示插入一条记录,多个括号以此类推 注意2:values后面括号内部插入的数据…

[C++] 由浅入深理解面向对象思想的组成模块

文章目录 (一) 类的默认成员函数(二) 构造函数构造函数的特征构造函数示例无参构造带参构造 冲突:全缺省参数的构造函数与无参构造函数 &#xff08;三&#xff09;析构函数特性析构函数的析构过程解析 &#xff08;四&#xff09;拷贝构造函数什么是拷贝构造&#xff1f;特性为…

Solana Blink和SEND的崛起:技术与市场效应的结合

随着Solana生态系统的不断发展&#xff0c;新的项目和技术不断涌现&#xff0c;吸引了大量的关注和投资。最近&#xff0c;Solana的Blink项目及其相关的SEND代币成为了市场的焦点&#xff0c;引发了广泛的讨论和投资热潮。本文将探讨Blink和SEND的技术创新、市场表现以及未来的…

大模型高效参数微调技术

文章目录 一、Fine-Tuning&#xff1a;微调二、Prompt-Tuning&#xff1a;提示调优2.1 工作原理2.2 PET (Pattern-Exploiting Training)2.3 Prompt-Tuning集成2.4 模板构建方式 三、Prefix Tuning&#xff1a;连续提示模板3.1 提出动机3.2 工作原理 四、P-Tuning V1/V24.1 P-Tu…

NFT如何解决音乐版权的问题

音乐版权问题一直困扰着音乐产业。传统的音乐版权管理模式存在以下问题。需要注意的是&#xff0c;NFT在音乐版权领域仍处于早期发展阶段&#xff0c;存在一些需要解决的问题&#xff0c;例如技术标准不统一、应用场景有限、法律法规不明朗等。但随着技术的进步和市场的完善&am…

【分库】分库的设计与原则、数据分片策略、垂直分库与水平分库、数据库引擎选择与配置优化

目录 引言 分库设计原则 数据分片策略的选择 垂直分库 vs 水平分库的比较 数据库引擎选择与配置优化 引言 在面对日益增长的数据量和不断升级的业务需求时&#xff0c;传统的单体数据库架构往往难以应对高并发、大数据量带来的性能瓶颈。为了突破这些限制&#xff0c;分库…

windows USB 设备驱动开发-USB 功能控制器驱动开发(二)

USB 功能客户端驱动程序使用的 UFX 对象和句柄 USB 函数类扩展 (UFX) 使用 WDF 对象功能来定义这些特定于 USB 的 UFX 对象。 重要的 API UfxDeviceCreateUfxEndpointCreate USB 函数类扩展 (UFX) 使用 WDF 对象功能来定义这些特定于 USB 的 UFX 对象。 这些对象是 WDF 对…

怎样优化 PostgreSQL 中对复杂条件筛选的执行效率?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 怎样优化 PostgreSQL 中对复杂条件筛选的执行效率&#xff1f;一、理解复杂条件筛选的挑战二、优化索引…

实现多层感知机

目录 多层感知机&#xff1a; 介绍&#xff1a; 代码实现&#xff1a; 运行结果&#xff1a; 问题答疑&#xff1a; 线性变换与非线性变换 参数含义 为什么清除梯度&#xff1f; 反向传播的作用 为什么更新权重&#xff1f; 多层感知机&#xff1a; 介绍&#xff1a;…

Linux: Mysql环境安装

Mysql环境安装&#xff08;Centos&#xff09; 前言一、卸载多余环境1.1 卸载mariadb1.2 查看并卸载系统mysql和mariadb安装包 二、换取mysql官方yum源三、安装并启动mysql服务3.1 yum源加载3.2 安装yum源3.3 安装mysql服务3.3.1 安装指令3.3.2 GPG密钥问题解决方法3.3.3 查看是…

LabVIEW液压数据采集测试系统

液压系统是装载机的重要组成部分&#xff0c;通过液压传动和控制实现各项作业功能&#xff0c;如提升、倾斜、转向等。液压系统的性能直接影响装载机的作业效率和稳定性。为了保证装载机液压系统的正常运行和优化设计&#xff0c;需要对其进行数据采集和测试。本文介绍了一套基…

Python酷库之旅-第三方库Pandas(022)

目录 一、用法精讲 55、pandas.lreshape函数 55-1、语法 55-2、参数 55-3、功能 55-4、返回值 55-5、说明 55-6、用法 55-6-1、数据准备 55-6-2、代码示例 55-6-3、结果输出 56、pandas.wide_to_long函数 56-1、语法 56-2、参数 56-3、功能 56-4、返回值 56-5…

Linux文件压缩与解压缩

在Linux中&#xff0c;tar实用程序是用于创建、管理和提取存档的常用命令。 tar实用程序的常用选项 执行tar操作需要以下tar命令操作之一&#xff1a; -c &#xff0c;--create &#xff1a;创建存档文件&#xff08;即压缩文件&#xff09;。-t&#xff0c;--list&#xff1…

0708,LINUX目录相关操作 + LINUX全导图

主要是冷气太足感冒了&#xff0c;加上少吃药抗药性差&#xff0c;全天昏迷&#xff0c;学傻了学傻了 01&#xff1a;简介 02&#xff1a; VIM编辑器 04&#xff1a;目录 05&#xff1a;文件 03&#xff1a;常用命令 06&#xff1a;进程 07&#xff1a;进程间的通信 cat t_c…

数据结构(4.1)——串的存储结构

串的顺序存储 串&#xff08;String&#xff09;的顺序存储是指使用一段连续的存储单元来存储字符串中的字符。 计算串的长度 静态存储(定长顺序存储) #define MAXLEN 255//预定义最大串为255typedef struct {char ch[MAXLEN];//每个分量存储一个字符int length;//串的实际长…

接口安全配置

问题点&#xff1a; 有员工在工位在某个接口下链接一个集线器&#xff0c;从而扩展上网接口&#xff0c;这种行为在某些公司是被禁止的&#xff0c;那么网络管理员如何控制呢&#xff1f;可以配置接口安全来限制链接的数量&#xff0c;切被加入安全的mac地址不会老化&#xff…

开源模型应用落地-工具使用篇-Spring AI-Function Call(八)

​​​​​​​一、前言 通过“开源模型应用落地-工具使用篇-Spring AI&#xff08;七&#xff09;-CSDN博客”文章的学习&#xff0c;已经掌握了如何通过Spring AI集成OpenAI和Ollama系列的模型&#xff0c;现在将通过进一步的学习&#xff0c;让Spring AI集成大语言模型更高阶…