Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Android注释处理POST请求_Java_Android_Serialization_Android Annotations_Spring Android - Fatal编程技术网

Java 使用Android注释处理POST请求

Java 使用Android注释处理POST请求,java,android,serialization,android-annotations,spring-android,Java,Android,Serialization,Android Annotations,Spring Android,我正在尝试使用AA使用RESTful API。我的API接收电子邮件和密码请求参数(不是JSON!),并返回一个APIKey(我使用Jackson2进行反序列化) 理想情况下,我希望使用常规的映射发送电子邮件和密码,但AA似乎要求我使用多值映射(这是映射),或自定义类(事件,没有显示源代码) 使用多值映射时,会发送一个数组。我发送的不是一系列电子邮件和密码,而是单个电子邮件和密码: // LoginFragment.java MultiValueMap<String

我正在尝试使用AA使用RESTful API。我的API接收电子邮件和密码请求参数(不是JSON!),并返回一个
APIKey
(我使用Jackson2进行反序列化)

理想情况下,我希望使用常规的
映射
发送电子邮件和密码,但AA似乎要求我使用
多值映射
(这是
映射
),或自定义类(
事件
,没有显示源代码)

使用
多值映射
时,会发送一个
数组
。我发送的不是一系列电子邮件和密码,而是单个电子邮件和密码:

// LoginFragment.java            
MultiValueMap<String, String> credentials = new LinkedMultiValueMap<String, String>();
credentials.add("email", email);
credentials.add("password", password);
APIKey resp = userRest.login(credentials);


// UserRest.java
@Post("user/login")
public APIKey login(MultiValueMap credentials);
//LoginFragment.java
多值映射凭据=新建LinkedMultiValueMap();
凭证。添加(“电子邮件”,电子邮件);
凭证。添加(“密码”,密码);
APIKey resp=userRest.login(凭证);
//UserRest.java
@Post(“用户/登录”)
公钥登录(多值映射凭证);
这会破坏我的API,因为它需要的是字符串而不是字符串数组


因此,我想我必须创建一个自定义的
凭证
对象来保存我的电子邮件和密码,并以某种方式将其序列化以发送到服务器。有人能帮我解决这个问题吗?

你没有考虑过使用Android注解提供的内置身份验证机制吗?像Basic Auth还是OAuth?这可能是一个更干净的解决方案

我使用了基本的身份验证选项-

您只需向接口添加一个方法:

void setHttpBasicAuth(String username, String password);
然后在进行API调用之前调用它。OAuth应该有一个类似的选项

编辑: 您可以创建登录POJO以发布到API:

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
        "name",
        "password"

})
public class Login{
    @JsonProperty("name")
    private String name;
    @JsonProperty("password")
    private String password;

}
然后在API界面中,您可以执行以下操作:

  @Post("user/login")
    public APIKey login(Login credentials);

然后将数据发布到/user/login方法。您可能需要添加一个拦截器,这取决于您希望解析ie
converters={MappingJacksonHttpMessageConverter.class}
等的数据类型。

我知道您已经找到了它,但请查看我使用的其余拦截器。基本上,它将一个api_密钥、访问_令牌和一个hmac_sig附加到头中的每个请求。然后您可以验证credientials服务器端

@EBean(scope = Scope.Singleton)
public class RestInterceptor implements ClientHttpRequestInterceptor {

private int requestCount = 0;

@Pref
MyPrefs_ myPrefs;

private RequestListener mRequestListener;

public interface RequestListener {
    void report(int count);
}

public void setOnRequestListener(RequestListener requestListener) {
    this.mRequestListener = requestListener;
}

public ClientHttpResponse intercept(HttpRequest request, byte[] data, ClientHttpRequestExecution execution)
        throws IOException {

    if (mRequestListener != null) {
        requestCount++;
        mRequestListener.report(requestCount);
    }

    HttpHeaders headers = request.getHeaders();

    long unixTime = System.currentTimeMillis() / 1000L;

    headers.add("request_time", String.valueOf(unixTime));

    if (myPrefs.accessToken().exists()) {

        headers.add("access_token", myPrefs.accessToken().get());


        String hmacInput; //left this part out but basically do something unique to the request here and do the same on the other side.

        String hmacKey = myPrefs.accessToken().getOr("");


        try {
            String hmacSig = hmacSha1(hmacInput, hmacKey);

            headers.add("hmac_sig", hmacSig);

        }
        catch (InvalidKeyException e) {

            e.printStackTrace();
        }
        catch (NoSuchAlgorithmException e) {

            e.printStackTrace();
        }


    }
    if (myPrefs.userId().exists()) {
        headers.add("user_id", String.valueOf(myPrefs.userId().get()));
    }

    headers.add("api_key", "somerandomstring");

    ClientHttpResponse t = execution.execute(request, data);

    if (mRequestListener != null) {

        requestCount--;
        mRequestListener.report(requestCount);
    }

    return t;
}


public void resetRequestCount() {
    this.requestCount = 0;
}

public static String hmacSha1(String value, String key) throws UnsupportedEncodingException,
        NoSuchAlgorithmException, InvalidKeyException {
    String type = "HmacSHA1";
    SecretKeySpec secret = new SecretKeySpec(key.getBytes(), type);
    Mac mac = Mac.getInstance(type);
    mac.init(secret);
    byte[] bytes = mac.doFinal(value.getBytes());
    return bytesToHex(bytes);
}

private final static char[] hexArray = "0123456789abcdef".toCharArray();

private static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for (int j = 0; j < bytes.length; j++) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}
@EBean(scope=scope.Singleton)
公共类RestInterceptor实现ClientHttpRequestInterceptor{
private int requestCount=0;
@优先股
MyPrefs_uuMyPrefs;
私有请求侦听器mRequestListener;
公共接口请求侦听器{
无效报告(整数计数);
}
public void setOnRequestListener(RequestListener RequestListener){
this.mRequestListener=requestListener;
}
公共ClientHttpResponse截获(HttpRequest请求,字节[]数据,ClientHttpPrequesteExecution执行)
抛出IOException{
if(mRequestListener!=null){
requestCount++;
mRequestListener.report(requestCount);
}
HttpHeaders=request.getHeaders();
long unixTime=System.currentTimeMillis()/1000L;
headers.add(“request_time”,String.valueOf(unixTime));
如果(myPrefs.accessToken().exists()){
headers.add(“access_token”,myPrefs.accessToken().get());
String hmacInput;//省略了这一部分,但基本上是在这里执行请求特有的操作,并在另一端执行相同的操作。
字符串hmacKey=myPrefs.accessToken().getOr(“”);
试一试{
字符串hmacSig=hmacSha1(hmaciput,hmacKey);
标题。添加(“hmac_sig”,hmacSig);
}
捕获(InvalidKeyException e){
e、 printStackTrace();
}
捕获(无算法异常){
e、 printStackTrace();
}
}
如果(myPrefs.userId().exists()){
headers.add(“user_id”,String.valueOf(myPrefs.userId().get());
}
添加(“api_键”、“somerandomstring”);
ClientHttpResponse t=execution.execute(请求、数据);
if(mRequestListener!=null){
请求计数--;
mRequestListener.report(requestCount);
}
返回t;
}
public void resetRequestCount(){
this.requestCount=0;
}
公共静态字符串hmacSha1(字符串值,字符串键)引发UnsupportedEncodingException,
NoSuchAlgorithmException,InvalidKeyException{
字符串类型=“HmacSHA1”;
SecretKeySpec secret=新的SecretKeySpec(key.getBytes(),type);
Mac Mac=Mac.getInstance(类型);
mac.init(秘密);
byte[]bytes=mac.doFinal(value.getBytes());
返回bytesToHex(字节);
}
私有最终静态字符[]hexArray=“0123456789abcdef”.toCharArray();
私有静态字符串bytesToHex(字节[]字节){
char[]hexChars=新字符[bytes.length*2];
INTV;
对于(int j=0;j>>4];
hexChars[j*2+1]=hexArray[v&0x0F];
}
返回新字符串(hexChars);
}

}

此API不支持基本身份验证,而login()是一个POST请求,因此附加到URL不会解决我的问题(我也不确定这是否安全)。事实上,我确实使用了该页面中的拦截器模式为所有请求注入必要的API密钥。然而,我的问题是关于发送带有Android注释的POST数据,而不是验证。我特别寻找一种方法(可能是POJO?)通过POST发送电子邮件和密码(即:电子邮件)=me@example.com,密码=示例)。他们在示例中使用的事件类找不到。