在本文中,我们将为您详细介绍使用JSF2.0在命名容器内获取组件clientId的完整前缀的相关知识,此外,我们还会提供一些关于@FeignClient注解中属性contextId的使用说明、ajax
在本文中,我们将为您详细介绍使用JSF 2.0在命名容器内获取组件clientId的完整前缀的相关知识,此外,我们还会提供一些关于@FeignClient注解中属性contextId的使用说明、ajax – 如何处理循环命名容器中的组件、android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2、Android+PHP 使用HttpClient提交POST的请求,使用JSON解析响应的有用信息。
本文目录一览:- 使用JSF 2.0在命名容器内获取组件clientId的完整前缀
- @FeignClient注解中属性contextId的使用说明
- ajax – 如何处理循环命名容器中的组件
- android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2
- Android+PHP 使用HttpClient提交POST的请求,使用JSON解析响应
使用JSF 2.0在命名容器内获取组件clientId的完整前缀
我正在通过JSF中的AJAX更新组件:
<h:form> <h:outputLink>Click me <f:ajax event="click" render=":messages" /> </h:outputLink></h:form><h:messages id="messages" globalOnly="true" />
由于<h:messages />
居住在外面,<h:form />
我必须在ID前面加上冒号(:
)。这可行。
但是,如果我将相同的代码放入组件中并将该组件包括到我的页面中,则代码将失败。原因是:messages
声明是指组件层次结构的根,而<h:messages/>
我要更新的组件实际上位于我的自定义组件下,该组件位于页面下(因此位置为style):myComponent:messages
。
在组件内部,如何获得<h:messages/>
组件的正确前缀?我知道我可以手动将ID分配给我的组件,并使用该ID为引用添加前缀(例如:#{cc.attrs.id}:messages
)。但是,我不知道此组件位于组件层次结构的哪个级别,因此所需的前缀甚至可能是:foo:bar:x:y:messages
。
答案1
小编典典似乎您可以通过表达式语言(EL)隐式对象(cc
和component
)访问当前前缀:
cc.clientId
返回当前 复合 组件的前缀component.clientId
返回任何当前组件的前缀。
例如,在页面中,通过
<myComponent id="foo">
在此组件内部,可以像这样获取客户端ID:
<h:outputText id="bar"> <p>ClientId for the composite component: #{cc.clientId}</p> <p>ClientId for current any component: #{component.clientId}</p></h:outputText>
以下内容应打印为:
ClientId for the composite component: fooClientId for current any component: foo:bar
我从博客文章JSF中获得了指针:使用组件标识符(id /
clientId)。它声明这是JSF 2.0的新功能。在此之前,人们必须以编程方式从备用Bean中获取ID。
@FeignClient注解中属性contextId的使用说明
一、概述
如果我们使用Feign定义了两个接口,但是目标服务是同一个,那么在SpringBoot启动时就会遇到一个问题:
Description:
The bean ''xxxxxxxx.FeignClientSpecification'', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
二、解决方案
2.1 方案1
修改yml配置:spring.main.allow-bean-definition-overriding=true
spring: main: allow-bean-definition-overriding: true
2.2 方案2
在每个Feign的接口中,在注解上加 contextId属性
contextId在Feign Client的作用是在注册Feign Client Configuration的时候需要一个名称,名称是通过getClientName方法获取的
@FeignClient(name = "sale-service",contextId= "saleservice1") public interface saleClient{ @RequestMapping(value = "/sale/add", method = RequestMethod.GET) String add(@RequestParam("saleNum") String queryStr); }
备注:contextId= "名称" 中的名称,不能用“_”会报错,可以用“-”
三、源代码分析
- 包名:spring-cloud-openfeign-core-2.2.5.RELEASE.jar
- 类路径:org.springframework.cloud.openfeign.FeignClientsRegistrar
相关代码1
private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes) { String className = annotationMetadata.getClassName(); BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class); this.validate(attributes); definition.addPropertyValue("url", this.getUrl(attributes)); definition.addPropertyValue("path", this.getPath(attributes)); String name = this.getName(attributes); definition.addPropertyValue("name", name); String contextId = this.getContextId(attributes); definition.addPropertyValue("contextId", contextId); definition.addPropertyValue("type", className); definition.addPropertyValue("decode404", attributes.get("decode404")); definition.addPropertyValue("fallback", attributes.get("fallback")); definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory")); definition.setAutowireMode(2); String alias = contextId + "FeignClient"; AbstractBeanDefinition beanDefinition = definition.getBeanDefinition(); beanDefinition.setAttribute("factoryBeanObjectType", className); boolean primary = (Boolean)attributes.get("primary"); beanDefinition.setPrimary(primary); String qualifier = this.getQualifier(attributes); if (StringUtils.hasText(qualifier)) { alias = qualifier; } BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, new String[]{alias}); BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry); }
代码截图:
相关代码2
可以看到, name应该是从注解中的属性取值来的, 再看看getClientName()方法.
private String getClientName(Map<String, Object> client) { if (client == null) { return null; } else { String value = (String)client.get("contextId"); if (!StringUtils.hasText(value)) { value = (String)client.get("value"); } if (!StringUtils.hasText(value)) { value = (String)client.get("name"); } if (!StringUtils.hasText(value)) { value = (String)client.get("serviceId"); } if (StringUtils.hasText(value)) { return value; } else { throw new IllegalStateException("Either ''name'' or ''value'' must be provided in @" + FeignClient.class.getSimpleName()); } } }
代码截图:
一目了然了, 我们声明@FeignClient注解时, 只使用了value属性, 所以产生了冲突, 只要加上contextId就好了.
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
- @FeignClient path属性路径前缀带路径变量时报错的解决
- 解决@RequestMapping和@FeignClient放在同一个接口上遇到的坑
- @FeignClient 实现简便http请求封装方式
- SpringCloud全面解析@FeignClient标识接口的过程
- 通过Feign进行调用@FeignClient 找不到的解决方案
- 浅谈@FeignClient中name和value属性的区别
ajax – 如何处理循环命名容器中的组件
<ui:repeat id="outerlist"> <my:compositeComponent id="myCC"> <h:panelgroup id="container"> Some content here (outputText,etc.) <ui:repeat id="innerlist"> <h:commandButton> <f:ajax render=":#{cc.clientId}:container" /> <!-- all closing tags accordingly -->
由于容器内的内容取决于内部列表按钮的操作,我需要更新它.当没有外部ui:重复时,如上所示的方法起作用.但是,如果存在组件未找到错误,则会失败.
这似乎是因为cc.clientId本身包含外部ui:repeat的行索引,例如,outerlist:0:myCC:容器.如a comment to this answer所示,该索引ID在视图树的服务器端表示中不可用.而是“行索引仅存在于客户端”.我必须承认,我不太明白这个索引是如何完成的以及服务器端的可用内容.
所以我的问题是:JSF如何进行这种索引,它(在服务器上)如何将ui内部的不同“实例”分开:重复,是否有解决方案,我想用上面的代码实现什么?
facesContext.getViewRoot().findComponent(clientId);
(因此可以找到它以便为ajax响应呈现其新的HTML表示)
并在JavaScript的客户端
document.getElementById(clientId);
(一旦新的HTML内容的ajax响应到达,它就可以被JS更新/替换)
作为< ui:repeat>仅在视图呈现时间内运行,具有行索引的客户机ID不代表服务器端的有效组件(来自findComponent()的“无法找到组件…”错误),但它确实表示客户端中的有效HTML元素侧.基本上,您需要客户端ID,而不需要服务器端的行索引和客户端的行索引.但这不适用于< ui:repeat>因为它(不幸的是)不可能通过单独的findComponent()来选择特定迭代轮次的组件树状态.
使用JSTL< c:forEach>时它应该可以正常工作并且在视图构建期间运行时动态分配组件ID,并且实际上在视图树中生成多个值得满足的JSF组件,而不是仅在渲染期间多次重复使用的组件.
<c:forEach varStatus="loop"> <my:compositeComponent id="myCC"> <h:panelGroup id="container_#{loop.index}"> Some content here (outputText,etc.) <ui:repeat id="innerlist_#{loop.index}"> <h:commandButton> <f:ajax render=":#{cc.clientId}:container_#{loop.index}" />
然而,这有其自身的含义,当然与复合组件一起使用时,以及在嵌套循环中使用时也是如此.您的代码不够完整,无法提供有关该代码的见解和建议.例如,当将这段代码放置在复合组件中时,它会断开,复合组件本身也在渲染时循环中重复使用多次.
也可以看看:
> JSTL in JSF2 Facelets… makes sense?
> How to find out client ID of component for ajax update/render? Cannot find component with expression “foo” referenced from “bar”
android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2
如果没有任何正确的答案,这个问题似乎正在蔓延.我希望现在应该解决. Google Angular Guys应该会有所帮助.
How to implement Google Auth in phonegap?
最接近的主题是How to use Google Login API with Cordova/Phonegap,但这不是angularjs的解决方案.
我不得不使用以下代码传输javascript变量值:
var el = document.getElementById('test'); var scopeTest = angular.element(el).scope(); scopeTest.$apply(function(){ scopeTest.user = user; scopeTest.logged_in = true; scopeTest.name = user.name; scopeTest.email = user.email; });
解决方法
.controller('TestCtrl',function($scope,$ionicPopup) { $scope.logged_in = false; $scope.getMember = function(id) { console.log(id); }; $scope.test = function(){ $ionicPopup.alert({"title":"Clicked"}); } $scope.call_google = function(){ googleapi.authorize({ client_id: 'CLIENT_ID',client_secret: 'CLIENT_SECRET',redirect_uri: 'http://localhost',scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email' }).done(function(data) { accesstoken=data.access_token; // alert(accesstoken); // $loginStatus.html('Access Token: ' + data.access_token); console.log(data.access_token); //$ionicPopup.alert({"title":JSON.stringify(data)}); $scope.getDataProfile(); }); }; $scope.getDataProfile = function(){ var term=null; // alert("getting user data="+accesstoken); $.ajax({ url:'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token='+accesstoken,type:'GET',data:term,dataType:'json',error:function(jqXHR,text_status,strError){ },success:function(data) { var item; console.log(JSON.stringify(data)); // Save the userprofile data in your localStorage. window.localStorage.gmailLogin="true"; window.localStorage.gmailID=data.id; window.localStorage.gmailEmail=data.email; window.localStorage.gmailFirstName=data.given_name; window.localStorage.gmailLastName=data.family_name; window.localStorage.gmailProfilePicture=data.picture; window.localStorage.gmailGender=data.gender; window.localStorage.gmailName=data.name; $scope.email = data.email; $scope.name = data.name; } }); //$scope.disconnectUser(); //This call can be done later. }; $scope.disconnectUser = function() { var revokeUrl = 'https://accounts.google.com/o/oauth2/revoke?token='+accesstoken; // Perform an asynchronous GET request. $.ajax({ type: 'GET',url: revokeUrl,async: false,contentType: "application/json",dataType: 'jsonp',success: function(nullResponse) { // Do something Now that user is disconnected // The response is always undefined. accesstoken=null; console.log(JSON.stringify(nullResponse)); console.log("-----signed out..!!----"+accesstoken); },error: function(e) { // Handle the error // console.log(e); // You Could point users to manually disconnect if unsuccessful // https://plus.google.com/apps } }); }; })
我正在为尝试使用Google OAuth2登录时面临类似问题的新手提供此答案.因此,我无耻地要求UpVotes,因为我也是新来的!
Android+PHP 使用HttpClient提交POST的请求,使用JSON解析响应
这里介绍一下如何让自己的android程序具有联网功能。当然首先要有一台服务器,如果只是进行测试的话,可以使用局域网代替(手机连电脑wifi)。
要求电脑已配置好Apache+PHP环境。
下面是一个简单的Android程序,相信只要有一定的Java基础就能大概“猜懂”其中的含义。(程序可能写的不够完善)
Android程序
布局文件
立即学习“PHP免费学习笔记(深入)”;
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingbottom="@dimen/<strong>Activity</strong>_vertical_margin" android:paddingleft="@dimen/<strong>Activity</strong>_horizontal_margin" android:paddingright="@dimen/<strong>Activity</strong>_horizontal_margin" android:paddingtop="@dimen/<strong>Activity</strong>_vertical_margin" tools:c android:orientation="vertical"><textview android:layout_width="match_parent" android:layout_height="wrap_content" android:>gravity="center" android:text="使用JSON解析" android:textSize="30sp"/> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:>gravity="center"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="账号" android:textsize="20sp" android:layout_marginright="20dp"></textview><edittext android:id="@+id/et_id" android:layout_width="match_parent" android:layout_height="wrap_content"></edittext></linearlayout><linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:>gravity="center"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密码" android:textsize="20sp" android:layout_marginright="20dp"></textview><edittext android:id="@+id/et_psw" android:layout_width="match_parent" android:layout_height="wrap_content"></edittext></linearlayout><button android:id="@+id/btn_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="登录"></button> </textview></linearlayout>
package com.example.jsontest; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.<strong>Apache</strong>.http.HttpEntity; import org.<strong>Apache</strong>.http.HttpResponse; import org.<strong>Apache</strong>.http.NameValuePair; import org.<strong>Apache</strong>.http.client.HttpClient; import org.<strong>Apache</strong>.http.client.entity.UrlEncodedFormEntity; import org.<strong>Apache</strong>.http.client.methods.HttpPost; import org.<strong>Apache</strong>.http.impl.client.DefaultHttpClient; import org.<strong>Apache</strong>.http.message.BasicNameValuePair; import org.<strong>Apache</strong>.http.protocol.HTTP; import org.json.JSONArray; import org.json.JSONObject; import android.os.Bundle; import android.os.Looper; import android.support.v7.app.ActionBar<strong>Activity</strong>; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class Main<strong>Activity</strong> extends ActionBar<strong>Activity</strong> { EditText et_id; EditText et_psw; Button btn_login; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.<strong>Activity</strong>_main); initView(); } private boolean check(String id, String psw) { if("".equals(id) || "".equals(psw)) return false; return true; } private void initView() { et_id = (EditText)findViewById(R.id.et_id); et_psw = (EditText)findViewById(R.id.et_psw); btn_login = (Button)findViewById(R.id.btn_login); btn_login.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //获取用户输入的用户名和密码 final String id = et_id.getText().toString().trim(); final String psw = et_psw.getText().toString().trim(); if(check(id, psw)) { new Thread() { public void run() { try { HttpPost post = new HttpPost("这里要改成服务器文件所在URL地址"); //如果传递参数个数比较多,可以对传递的参数进行封装 List<namevaluepair> params = new ArrayList<namevaluepair>(); params.add(new BasicNameValuePair("id", id)); params.add(new BasicNameValuePair("psw", psw)); //设置请求参数 post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); HttpClient httpClient = new DefaultHttpClient(); //发送POST请求 HttpResponse response = httpClient.execute(post); //如果服务器成功地返回响应 if(response.getStatusLine().getStatusCode() == 200) { //String msg = EntityUtils.toString(response.getEntity()); HttpEntity entity = response.getEntity(); InputStream is = entity.getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8); StringBuilder sb = new StringBuilder(); sb.append(reader.readLine() + "\n"); // 这里 “ + "\n" ”加不加似乎对结果没有什么影响 String line = "0"; while((line = reader.readLine()) != null) { sb.append(line + "\n"); // 这里 “ + "\n" ”加不加似乎对结果没有什么影响 } is.close(); //获取请求响应结果 String result = sb.toString(); System.out.println(result); //打包成JSON进行解析 JSONArray jsonArray = new JSONArray(result); JSONObject jsonData = null; //返回用户ID,用户密码 String userId = ""; String userPsw = ""; //使用List进行存储 List<string> data = new ArrayList<string>(); for(int i = 0; i 索引,根据<strong>索引</strong>获取值 userPsw = jsonData.getString("userPsw"); //userPsw是来源于服务器端php程序响应结果res的<strong>索引</strong>,根据<strong>索引</strong>获取值 data.add("用户ID:" + userId + ",用户密码:" + userPsw); //保存返回的值,可进行相应的操作,这里只进行显示 } Looper.prepare(); Toast.makeText(Main<strong>Activity</strong>.this, data.toString(), Toast.LENGTH_LONG).show(); Looper.loop(); } else { Looper.prepare(); Toast.makeText(Main<strong>Activity</strong>.this, "登录失败", Toast.LENGTH_LONG).show(); Looper.loop(); } } catch(<strong>Exception</strong> e) { e.printStackTrace(); } } }.start(); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent <strong>Activity</strong> in <strong>AndroidManifest.xml</strong>. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } </string></string></namevaluepair></namevaluepair>
而下面是一个服务器端php文件(文件内并未连接数据库的操作,如果希望的话,可以连接数据库,获取动态数据。对于php有所了解的人可以很容易的改成连接数据库获取数据的操作)
checkId.php
<?php //获取客户端发送过来的ID和密码 $id=$_POST['id']; $psw=$_POST['psw']; if($id == "admin" && $psw == "123") { $res=array(array()); $res[0]['userId']=$id; $res[0]['userPsw']=$psw; $res[1]['userId']="testId1"; $res[1]['userPsw']="testPsw1"; $res[2]['userId']="testId2"; $res[2]['userPsw']="testPsw2"; } echo json_encode($res); ?>
以上就介绍了Android+PHP 使用HttpClient提交POST的请求,使用JSON解析响应,包括了gravity,Apache,Exception,索引,连接数据库方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
关于使用JSF 2.0在命名容器内获取组件clientId的完整前缀的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于@FeignClient注解中属性contextId的使用说明、ajax – 如何处理循环命名容器中的组件、android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2、Android+PHP 使用HttpClient提交POST的请求,使用JSON解析响应的相关信息,请在本站寻找。
本文标签: