I have a problem getting URL parameter using Struts 1.2/1.3.
I use the URL myUrl/logon.jsp?myParam=123 which goes into the FormBean-reset()-function
public void reset(ActionMapping mapping, HttpServletRequest request) {...}
But the request-parameterMap is empty and I do not find the myParam nor the value.
Any idea what I am missing here?
Related
I want to build a library that will save the Json content of request and response on annotated Spring controller.
So i've build my own annotation #Foo and put it on some controllers:
#Foo
#RequestMapping(method = RequestMethod.POST, value = "/doSomeThing", produces = {
MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_XML_VALUE,
MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<T> doSomething(/*some parameters*/) {
T t = doSomeJob(T.class);
return new ResponseEntity<T>(t, HttpStatus.OK);
}
I have no guarantee that request and response are in Contrellor's parameters!
And i'm catching the call on any Controller having that annotation within an #AfterReturning AOP pointcut.
#Component
#Aspect
public class XYInterceptor
#AfterReturning(
pointcut = "execution(#my.annotation.Foo)")
public void doSomethingWithJsonContent(JoinPoint joinPoint) throws Throwable {
//How can i get json value of request and response here?
}
How can I get request and response content formatted in json (such as it is send/returned to the client) ?
Thanx for your help!
Well, you need request and response somehow accessible from your controller method, either via an injected class member, method parameter or method return value. It has got to be somewhere. Because you did not explain where you intend to get it from, I can just post a general answer showing how to determine method arguments and return value from an #AfterReturning advice. If you update the question with more detailed information, I can also update the answer accordingly.
My pointcut (the commented-out one also works, choose your favourite one) binds the return value to a parameter and just assumes that both request and response are of String type. Feel free to replace by your favourite. Furthermore, you can bind a parameter from your intercepted method (no matter where it is in the signature) to a typed advice method parameter if you know that the parameter exists and also know its (super) type. This way you can get rid of the slow and ugly loop over getArgs().
//#AfterReturning(pointcut = "execution(#my.annotation.Foo * *(..))", returning = "response")
#AfterReturning(pointcut = "#annotation(my.annotation.Foo)", returning = "response")
public void interceptRequest(String response, JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
if (arg instanceof String)
System.out.println(" request = " + arg);
}
System.out.println(" response = " + response);
}
I am a beginner in web api asp.net MVC and I have a problem.
I have a class that I will use in web api HttpGet and HttpPost:
public class Credit
{
public string Log {get; set;}
public string Pas {get; set;}
}
In the example API controller I have:
[HttpGet]
public void Login (Credit credit)
{
}
[HttpPost]
public void Login (Credit credit)
{
}
Tests of these methods in RestConsole in Google Chrome, sending json data:
{"Log", "test", "Pas": "test"}
When debugging these methods, I see that HttpPost is working properly and parameter of "credit" is filled with properties.
However HttpGet is not working properly, the object is not filled property, it is NULL.
Can someone explain to me this situation and how can I get the complete object in the HttpGet?
This is because of how Web API creates parameter values from the HTTP request.
By default, if the parameter is a "complex" type (such as your Credit class), Web API gets the parameter value from the body of the request. If the parameter is a "simple" type (e.g., int or string), then Web API gets the value from the request URI.
However, HTTP GET requests cannot have a request body. So by default you can't pass a complex type to a Web API "GET" method.
You can read more here: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
In any case, for a Login method, you probably should use a POST request, not a GET request.
I'm using Google Http Client and Jackson to query data to backend (JSON API).
I need to pass parameters (one Java bean object). The object might have few or lot of field. Initially I attempt to pass it as content as follow:
HttpRequest request = requestFactory.buildGetRequest(getUrl(api)).setContent(new JsonCContent(jsonFactory, params));
However, I'm not allowed to set the HTTP content in GET operation.
Any suggestion how can I pass these parameters?
Under one condition:
I don't want to write a util method to convert this object into string of URL parameters. But if there's already reusable API to do it, that would be fine.
I need generic solution if possible. Because I'm going to apply this to 600 JSON API calls.
My last alternative would be to change backend to expect POST request instead of GET, then I perform POST operation on the client side.
Thanks
Instead of extends GenericUrl, you can use GenericUrl.put (inherit from GenericData) to set query parameters. For example:
GenericUrl genericUrl = new GenericUrl("http://yourapi.com/request");
genericUrl.put("user", "user name");
genericUrl.put("token", "token values");
HttpRequest request = requestFactory.buildGetRequest(genericUrl);
It seems like the expected usage is to extend the URL class you are using for your buildGetRequest() call. For instance, let's say you wanted to provide two extra query parameters called "user" and "token". You could do this with the following:
HttpRequest request = requestFactory.buildGetRequest(
new CustomUrl("http://www.yourserver.com").setUser(userId).setToken(token));
where the CustomUrl class is defined as:
public class CustomUrl extends GenericUrl {
public CustomUrl(String encodedUrl) {
super(encodedUrl);
}
#Key("user")
private String mUserId;
#Key("token")
private String mToken;
public CustomUrl setUser(String userId) {
mUserId = userId;
return this;
}
public CustomUrl setToken(String token) {
mToken = token;
return this;
}
}
The values are not necessary for the #Key annotations, but will be used as the name of the respective query parameters if provided. If omitted, the name of the variable will be used instead (see example)
Check google-http-client's javadoc for more info.
For some reason, I haven't found any normal way to do the following:
I want to Post a json object, and add additional parameters to the call (in this case, an authentication token).
This is a simple RESTful server in myUrl/server, which should give access to different resources of a "person" in the url myUrl/server/person/personCode/resourceName.
GET is easy, and requires no object, only parameters.
The problem arrises when I get to POST - how do I attach the JSON, and keep the other parameters as well?
The class (much has been removed for clarity and proprietary reasons...):
//Handles the person's resources
#Path("/person/{personCode}/{resourceName}")
public class PersonResourceProvider {
#GET
#Produces("application/json")
public String getPersonResource(#PathParam("personCode") String personCode, #PathParam("resourceName") String resourceName, #DefaultValue("") #QueryParam("auth_token") String auth_token) throws UnhandledResourceException, UnauthorizedAccessException {
//Authenticates the user in some way, throwing an exception when needed...
authenticate(personCode, auth_token, resourceName);
//Returns the resource somehow...
}
#POST
#Produces("application/json")
public String postPersonResource(#PathParam("personCode") String personCode, #PathParam("resourceName") String resourceName, #DefaultValue("") #QueryParam("resourceData") String resourceData, #DefaultValue("") #QueryParam("auth_token") String auth_token) throws UnhandledResourceException, UnauthorizedAccessException {
//Again, authenticating
authenticate(personCode, auth_token, resourceName);
//Post the given resource
}
}
Now, the GET method works perfectly, when you go to
myUrl/person/personCode/resourceName, it gives me the correct resource.
The auth_token is used with every single call to the server (for now, authentication is done by comparing with a predefined string), so it's needed. All the other parameters are provided through the path, except for the authentication token, which should not be in the path as it does not relate to the identity of the required resource.
When I get to POST, it's a problem.
I know there's a way to tell the method it consumes a JSON, but in that case, what will happen to the other parameters (auth_token is one of them)?
Should I use Multipart?
Another related question, this is the first time I've designed such a server, is this design correct?
Thanks!
I am not sure I understand what you are trying to achieve. Let me try explain a few things - hope it will be relevant to your question:
#QueryParam injects parameters which are part of your path - i.e. the part of the URL that goes after "?".
E.g. if you have a URL like this:
http://yourserver.com/person/personCode/resourceName?resourceData=abc&token=1234
Then there would be 2 query params - one named resourceData with value "abc" and the other one named token with value "1234".
If you are passing an entity in the POST request, and that entity is of application/json type, you can simply annotate your post method using #Consumes("application/json") annotation and add another parameter to your method, which does not need to be annotated at all.
That parameter can be either a String (in that case Jersey would pass a raw JSON string and you would have to parse it yourself) or it can be a java bean annotated with #XmlRootElement annotation - in that case (if you also include jersey-json module on your classpath) Jersey will try to unmarshall the json string into that object using JAXB. You can also use Jackson or Jettison libraries to do that - see this section of Jersey User Guide for more info: http://jersey.java.net/nonav/documentation/latest/json.html
Found!
Client side:
Client c = Client.create();
WebResource service = c.resource("www.yourserver.com/");
String s = service.path("test/personCode/resourceName")
.queryParam("auth_token", "auth")
.type("text/plain")
.post(String.class, jsonString);
Server side:
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
#Path("/test/{personCode}/{resourceName}")
public class TestResourceProvider {
#POST
#Consumes("text/plain")
#Produces("application/json")
public String postUserResource(String jsonString,
#PathParam("personCode") String personCode,
#PathParam("resourceName") String resourceName,
#QueryParam("auth_token") String auth_token)
throws UnhandledResourceException {
//Do whatever...
}
}
In my case, I will parse the json I get in the server depending on the resource name, but you can also pass the object itself, and make the server consume an "application/json".
I'm trying to set up an action in ASP.NET MVC 3 to handle the payload of a mercurial webhook request - in this case, generated by Kiln.
The payload is JSON, but unfortunately it is sent as a URL encoded form value with the content type application/x-www-form-urlencoded, because apparently using application/json and sending it unencoded with no parameter name would make it too easy and um... standard.
This means that I can't just use the new JsonValueProviderFactory because it only picks up requests using the standard application/json content type. And of course I can't just kludge the factory to also pick up application/x-www-form-urlencoded requests too, because I need those requests to use the form data value provider everywhere else in my app that's actually receiving form data and not JSON.
So, is there a way I can specify that a ValueProvider or ValueProviderFactory should only be used for a specific action or route?
If you create a specific controller to handle these webhook requests, you can assign your unique ValueProvider when you instantiate your controller.
public class KilnController : Controller
{
public KilnController()
{
this.ValueProvider = MyCustomValueProvider;
}
...
}
This should fulfill your need for a custom ValueProvider for these requests.
Turns out that IValueProvider was not the particular bit of extensibility I was looking for - I just needed to use a quick IModelBinder implementation I found courtesy of James Hughes. It needed a little tweaking to cover pulling something out of the form:
public class JsonFormModelBinder : IModelBinder
{
#region [ ModelBinder Members ]
Object IModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
var jsonStringData = request.Form[bindingContext.ModelName];
if (jsonStringData != null) return JsonConvert.DeserializeObject(jsonStringData, bindingContext.ModelType);
else return null;
}
#endregion
}
And the usage:
[HttpPost]
public ActionResult WebHook([ModelBinder(typeof(JsonFormModelBinder))] WebHookMessage payload)
{
return Content("OK");
}