-1

I'm trying to generate custom HttpHeader in akka. I've a HashMap of header entries which I need to convert to Iterable. Here's my code:

import akka.http.javadsl.model.HttpHeader;
HashMap<String, String> headersMap = new HashMap<>();
headersMap.put("key1","value1");
return (Iterable<HttpHeader>) headersMap;
//HttpRequest.create().withUri("uri").addHeaders(Iterable<HttpHeader> iterable)
public static Iterable<HttpHeader> convertToRecordHttpHeaders(Map<String, String> headersMap){
    return headersMap.entrySet().stream()
            .map(x -> new HttpHeader(x.getKey(), x.getValue()))
            .collect(Collectors.toList());
}

What's the efficient way to convert the map to HttpHeader and convert it to Iterable as I want to create a HttpRequest in akka.

Solution: Used RawHeader to add headers to request

request.addHeader(RawHeader.create("key","value"));
Dookoto_Sea
  • 521
  • 1
  • 5
  • 16
  • Could you [edit] your question and clarify which library you are using (from where `HttpRequest` or `HttpHeader` comes from)? – Pshemo Apr 01 '22 at 18:03
  • I'm using import akka.http.javadsl.model.HttpHeader; getting an exception 'HttpHeader' is abstract; cannot be instantiated – Dookoto_Sea Apr 01 '22 at 18:39

2 Answers2

0

A HashMap is not an Iterable anything. Its entrySet(), keySet() and values() are, but for your map those are Iterable<Map.Entry<String, String>>, Iterable<String> and Iterable<String> respectively. That means that you cannot cast the map in any way to an Iterable<HttpHeader>.

What you can do is convert:

List<HttpHeader> headersList = headersMap.entrySet().stream()
        .map(entry -> new HttpHeader(entry.getKey(), entry.getValue())
        .collect(Collectors.toList()); // or just toList() with Java 17

This assumes that HttpHeader has a constructor that takes a header name and value. If it doesn't, replace the constructor call with something else that creates an HttpHeader.

Rob Spoor
  • 6,186
  • 1
  • 19
  • 20
  • I tried this to generate an Iterable for HttpHeader, getting an exception 'HttpHeader' is abstract; cannot be instantiated. – Dookoto_Sea Apr 01 '22 at 18:36
  • So my assumption doesn't hold. Check the documentation to see if there are sub classes, or otherwise a factory method. – Rob Spoor Apr 02 '22 at 10:32
  • I've seen your other comment and checked out https://doc.akka.io/japi/akka-http/current/akka/http/javadsl/model/HttpHeader.html. You can use `HttpHeader.parse(entry.getKey(), entry.getValue())`. – Rob Spoor Apr 02 '22 at 10:37
0

Lets say your Header class is something like this

class HttpHeader{
    public HttpHeader(Map.Entry<String,String> header){}
}

then just use constructor reference in place of lambda or else you can provide your parsing using lambda expression

headersMap.entrySet().stream().map(HttpHeader::new).iterator();

But still i don't understand the use case of creating HashMap for return HttpHeader iterator.

i guess you used to keep header keys unique viva map however you can use TreeSet that will maintain unique objects too


class HttpHeader implements Comparable<HttpHeader>{
    String key;
    String value;
    
    public HttpHeader(String key, String value){
        this.key = key;
        this.value = value;
    }

    @Override
    public int compareTo(HttpHeader o) {
        return key.compareTo(o.key);
    }
}
  • Calling `iterator()` on the stream returns an `Iterator`, not an `Iterable`. The latter is a functional interface that has a single `iterator()` method. You also can't use `::iterator` on the stream because you can only call any terminal operator once. – Rob Spoor Apr 02 '22 at 10:34