Dynamically add query parameters without value to Retrofit request - url

I have request that set list of services that are turned on for user.
Request has following format:
https://myserver.com/setservices?param1=val1&param2=val2&service[10]&service[1000]&service[10000]
List of service parameters ("service[10]&service[1000]&service[10000]") is created dynamically and each parameter doesn't have value. Is it possible to achive this using Retrofit?

From the retrofit documentation:
For complex query parameter combinations a Map can be used.
#GET("/group/{id}/users")
List<User> groupList(#Path("id") int groupId, #QueryMap Map<String, String> options);
I guess this will make what you want to achieve.

I found workaround how to do this.
#GET("/setservices{services_query}")
ServicesSetResponse setServices(#EncodedPath("services_query") String servicesQuery);
And then:
getService().setServices("?param1=val1&param2=val2" + "&services[10]&services[100000]&services[1000000]")

We can pass using the #QueryMap as below:
GET("/movies")
Call<List<Movies>> getMovies(
#QueryMap Map<String, String> options
);
To build the parameters:
Map<String, String> data = new HashMap<>();
data.put("director", "Haresh");
data.put("page", String.valueOf(2));
It will generate the Url like:
http://your.api.url/movies?page=2&director=Haresh

Related

AngularDart CurrentInstruction

I am trying to update angular2 to latest version. Several of the functions are missing
I would like to know what is the alternate for the following function
final RouteParams _params;
String get routeName => _router.currentInstruction.component.routeName;
How to get routeName from new AngularDart
Not possible to access current component route anymore.
I don't know what you want to do exactly and how you define your routeName, but you probably need to use additionalData of RoutePath or RouteDefinition
class AdditionalRouteData {
final String routeName;
const AdditionalRouteData({this.routeName});
}
final routePath = RoutePath(
path: '/',
additionalData: AdditionalRouteData(routeName: 'Home'),
);
// then get it that way
(router.current.routePath.additionalData as AdditionalRouteData).routeName;
However, if your routeName is dynamic, you must find a new way to access it (without the router, using a service via dependency injection)

java.lang.IllegalArgumentException: URL query string must not have replace block [duplicate]

This question already has an answer here:
Retrofit with an old school service
(1 answer)
Closed 3 years ago.
I am using Retrofit and GET Request:
#GET("Master/GetConsignerPartyList?prefix={claimId}")
Observable<ConsignerPartyResponse> consignerPartyReq(#HeaderMap Map<String, String> headers, #Path("claimId") String search);
and getting this error:
java.lang.IllegalArgumentException: URL query string "prefix={claimId}" must not have replace block. For dynamic query parameters use #Query.
What's going wrong?
Remove ?prefix={claimId} from your url because query name should not be static in url.
#GET("Master/GetConsignerPartyList")
Observable<ConsignerPartyResponse> consignerPartyReq(
#HeaderMap Map<String, String> headers,
#Query("prefix") String search);
It's will work :-)
claimId is part of the query as you've set it in the URL - ?prefix={claimId}"
#Path replaces placeholders in the path, i.e., #GET("Master/{claimId}/").
To replace in the query just use #Query("claimId"):
#GET("Master/GetConsignerPartyList?prefix={claimId}")
Observable<ConsignerPartyResponse> consignerPartyReq(
#HeaderMap Map<String, String> headers,
#Query("claimId") String search);

Disallow broadcast in convertAndSendToUser method in SimpMessagingTemplate

I am working with Spring websocket implementation. For sending a message to clients, there are two ways:
1) Using #SendToUser annotation
2) Using convertAndSendToUser method of SimpMessagingTemplate
#SendToUser takes a boolean parameter called broadcast which if set to false publishes the message to the current session. Is there a way I can have this behaviour in SimpMessagingTemplate.
If we take a look to the SendToMethodReturnValueHandler source code, we'll see:
if (broadcast) {
this.messagingTemplate.convertAndSendToUser(user, destination, returnValue);
}
else {
this.messagingTemplate.convertAndSendToUser(user, destination, returnValue, createHeaders(sessionId));
}
So, what you need for your use-case just use that overloaded convertAndSendToUser and provide a Map with `sessionId:
messagingTemplate.convertAndSendToUser(user, destination, payload,
Collections.singletonMap(SimpMessageHeaderAccessor.SESSION_ID_HEADER, sessionId))
Spring doesn't have a clear document, I tried many different way, only below code works for me.
SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.create();
accessor.setHeader(SimpMessageHeaderAccessor.SESSION_ID_HEADER, sessionId);
messagingTemplate.convertAndSendToUser(sessionId, destination, payload, accessor.getMessageHeaders());
The answer above did not work for me. It turns out that with Spring 4.1.4 something slightly different is required.
The way that seems the cleanest to me looks like the following:
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create();
headerAccessor.setSessionId(cmd.getSessionId());
headerAccessor.setLeaveMutable(true);
MessageHeaders messageHeaders = headerAccessor.getMessageHeaders();
messagingTemplate.convertAndSendToUser(cmd.getPrincipal().getName(),
"/queue/responses", ret, messageHeaders);
The other way which worked was to explicitly add a "nativeHeaders" value to the Map sent to SimpMessagingTemplate.convertAndSendToUser(). However, this way seems to depend too much on implementation details:
Map<String, Object> headers = new HashMap<>();
headers.put("nativeHeaders", new HashMap<String, Object>());
headers.put(SimpMessageHeaderAccessor.SESSION_ID_HEADER, cmd.getSessionId());
messagingTemplate.convertAndSendToUser(cmd.getPrincipal().getName(),
"/queue/responses", ret, headers);
The "offending code" which made setting the "simpSessionId" header and nothing else in a Map not work was in SimpMessagingTemplate.processHeaders() and MessageHeaderAccessor.getAccessor(MessageHeaders, Class requiredType).
The simplest way send to User by SimpMessagingTemplate
#Autowired
private SimpMessagingTemplate messagingTemplate;
#MessageMapping("/getHello")
public void sendReply( MessageHeaders messageHeaders, #Payload String message, #Header(name = "simpSessionId") String sessionId){
messagingTemplate.convertAndSendToUser(sessionId, "/queue/hello", "Hello "+ message, messageHeaders);
}

retrieve FacesContext sessionMap from an other context

I have a method to remove a session managed bean
public void invalidMyBean()
{
final Map<String, Object> sessionMap = FaceContext.getCurrentInstance().getExternalContext().getSessionMap();
sessionMap.remove("mySessionBean");
}
invalidMyBean() is also called from a Web Service.
In this case FaceContext.getCurrentInstance() is null, and I can't remove my bean.
I tried to store sessionMap as a field in my class, but removing from this object does'nt work.
Is there a way to retrieve sessionMap outside from a faceContext ?
thx
The ExternalContext#getSessionMap() is just an abstraction of HttpSession#get/set/removeAttribute(). So wherever you are in the servletcontainer (filter, servlet, webservice, whatever), once you've got a hand of the concrete HttpSession instance, then you should be able to use session.removeAttribute("mySessionBean") on it.
Note that this obviously only works when the webservice is been requested using the same HTTP session as the JSF application (the way you put this question — you seem to not understand at all how HTTP sessions work — suggests that this is not the case).
I answer to myself giving the working code for an applet in a JSF page sharing the same HttpSession. The applet talks to a web service on the server using JAX-WS.
in JSF page :
<applet ..>
<param name="commonSessionId" value="#{session.id}" />
Distance Sensor [Your browser doesn’t seem to support Java applets.]
</applet>
in applet init() :
#Override
public void init()
{
...
commonSessionId = getParameter("commonSessionId");
port = service.getWsAppletPort();
final Map<String, Object> map = new HashMap<String, Object>();
map.put("Cookie", Collections.singletonList("JSESSIONID=" + commonSessionId));
final Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();
requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, map);
requestContext.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);
}
thanks again to BalusC for his great help !!

Pass dynamic parameters in the keyvalue (message key) to package.properties

I have tried to pass dynamic parameters to keyvalue(message to display) which I will get from package.properties to the Action class through the getText() method. To get the message, we can use getText(String keyvalue) method. What should I do to pass some parameters and retrieve the parameters with the message through the getText() method?
I saw some API's to pass dynamic parameters. But I don't know how to use, these are the following API's, click here to see the Struts 2 API Documentation.
getText(String aTextName, List<Object> args)
getText(String key, String[] args)
getText(String key, String defaultValue, String[] args)
Thanks in advance..
I suppose that you have following properties in your package.properties
username.required=user name is required
password.required=password is required
you can use getText() as
getText("username.required")
getText("password.required")
Now if we want to use getText(String key, String[] args) we have to pass following parameters
aTextName - the resource bundle key that is to be searched for
args - a list args to be used in a MessageFormat message
That means the message format pattern and other static strings will, of course, be obtained from resource bundles. Other parameters will be dynamically determined at runtime.
example
we have following entry in resource file
disk.data=The disk \"{0}\" artist name is {1}.
in this {1} and {0} are the dynamic parameters and will be determined at run time so args will contain the value of these parameters.
String artistName= demo;
String diskName = "Artist";
String[] testArgs = {artistName, diskName};
So final call will be getText(disk.data, testArgs);
and it will show
The disk demo artist name is Artist.
Please go through MessageFormat to know how this work

Resources