Portlet #resourceMapping and Multipart as parameter - java

I use Liferay and I have code:
#ResourceMapping(value = "keaFileUpload")
public ModelAndView fileUpload(ResourceRequest request, ResourceResponse response,
ModelMap modelMap) throws PortalException, SystemException {
// code
}
How can I use Multipart as parameter request? For example MultipartHttpServletRequest?
When I use it instead of ResourceRequest request I have error.

When the form is multipart/form-data you should get extra parameter(like "name") from UploadPortletRequest instead of ResourceRequest.
correct form of getting parameter:
UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(request);
String name = ParamUtil.getString(uploadRequest,"name");
Also you can check out this link
https://www.liferay.com/community/forums/-/message_boards/message/17237791

Related

Developing under Spring Framework, how to get the current URL inside a form response?

This is a REST application using Spring Framework.
Look, in some point of the payment process, I request the form to redirect to the payment URL:
#RequestMapping( value="/{id}/online-payment", produces="text/html", method={ RequestMethod.POST, RequestMethod.GET } )
#ResponseBody
public String onlinePaymentForm( HttpServletResponse response,
#PathVariable( value="id" )String eventId,
#RequestParam( value="temporalDataId", required=true )String temporalDataId,
#RequestParam( value="amount", required=true )Double amount
) throws Exception
{
...
else if( conn.getGateway() == PaymentGateway.PAYPAL)
{
return paypalPaymentsServices.buildPaymentForm(
conn, temporalDataId, amount, event.getName(), data.representantParticipant() );
}
...
}
When the application gets the form, auto submit the obtained form (onload=submitForm()). What I want to do is to put the current URL or the current domain name in the response form, for example:
I know how to do it using HttpServletRequest request with request.getRequestURL(), but as you can see this method is receiving an HttpServletResponse response.
Maybe exists is a class with static methods or a way to get the current URL using Spring Framework or Java?
Thanks.
If you add a request parameter, then you should be able to use it; e.g.
#RequestMapping(value="/{id}/online-payment", produces="text/html",
method={RequestMethod.POST, RequestMethod.GET})
#ResponseBody
public String onlinePaymentForm(
HttpServletResponse response,
HttpServletRequest request,
#PathVariable(value="id") String eventId,
#RequestParam(value="temporalDataId", required=true) String id,
#RequestParam(value="amount", required=true) Double amount
) {
...
}
The mapping infrastructure recognizes and binds a HttpServletRequest parameter if you are within a Servlet based container.

Request Header is getting as null in spring mvc

I am having two mapping methods in my controller. one is redirecting to other.
Before redirecting I'm setting a header in response. But I getting the request header as null.
These are my methods in controller. both are in same controller.
#RequestMapping(value="/testStart", method=RequestMethod.POST)
public String testStart(HttpServletRequest request, HttpServletResponse response){
String token = "126712810-1289291":
response.addHeader("authToken", token);
return "redirect:/test";
}
#RequestMapping(value="/test", method={ RequestMethod.POST, RequestMethod.GET })
public String getTestPage(Model model, HttpServletRequest request, HttpServletResponse response){
String token = request.getHeader("authToken");
System.out.println(token); //prints null
model.addAttribute("Testtoken", token);
System.out.println("Test page about to load ..");
return "test";
}
I'm using postman client to test this api. It is hitting the url and redirecting to other url. but the header is null.
I don't know what's wrong. can any one help me to figure this out? Thanks
With Redirect method web app tells browser to load the page which you want to redirect. So this makes new http request from browser, the original requests are not reachable at this moment.
So your problem can be solved with Forward method. Web app forwards all request data to another handler method internally
return "forward:/test";
Additionally , please change your
String token = request.getHeader("authToken");
with
String token = response.getHeader("authToken");
because you are adding your authToken to the response object.(from comments HttpServletResponse -> getHeader(String name) works since Servlet 3.0)
EDIT :
this code will be your complete solution "/test" method supports forwarded reuqest and also supports request from browser.
(You want to get token info from request becuase you want to call /test method without forwarding, so it works in this way, but when forwarding you cant add header so you tried to add in response and get it from request but that doesnt work in that way so you need to resolve token according to dispatcher's type so check the code )
#RequestMapping(value="/testStart", method=RequestMethod.POST)
public String testStart(HttpServletRequest request, HttpServletResponse response){
String token = "126712810-1289291";
request.setAttribute("authToken", token);
return "forward:/test";
}
#RequestMapping(value="/test", method={ RequestMethod.POST, RequestMethod.GET })
public String getTestPage(Model model, HttpServletRequest request, HttpServletResponse response)
{
//-----------------
//resolving token
String token = null;
DispatcherType type = request.getDispatcherType();
if(type == DispatcherType.FORWARD)
{
token = (String) request.getAttribute("authToken");
}
else if(type == DispatcherType.REQUEST)
{
token = (String) request.getHeader("authToken");
}
//-----------------
System.out.println(token); //prints the value
model.addAttribute("Testtoken", token);
System.out.println("Test page about to load ..");
return "test";
}
Use RedirectAttributes to pass parameters with redirect URL:
#RequestMapping(value="/test1", method=GET)
public String test(RedirectAttributes redirectAttributes){
redirectAttributes.addAttribute("authToken", "val");
return "redirect:/test";
}
or if you can use forward:/test you can go with request.setAttribute and request.getAttribute
Still if you want to add in header then use RestTemplate and HTTPHeaders and get the response String

What's the difference between #ResponseBody and HttpServletResponce

When I tried to user Micro Message Public Platform, the weChat server will invoke one of my API and I need to return a token to validate my identity. However,when I return the token directly like this, the weChat server alerts that validation is error.
#RequestMapping(value="/userFollow", method= RequestMethod.GET)
#ResponseBody
public String weChatToken(HttpServletRequest request,String signature,String timestamp,String nonce,String echostr,HttpServletResponse response) throws IOException, DocumentException {
String result=weChatService.checkSignature(signature,timestamp,nonce,echostr);
return result;
}
Then I changed my code as below. This time, the validation is correct.
#RequestMapping(value="/userFollow", method= RequestMethod.GET)
#ResponseBody
public String weChatToken(HttpServletRequest request,String signature,String timestamp,String nonce,String echostr,HttpServletResponse response) throws IOException, DocumentException {
String result=weChatService.checkSignature(signature,timestamp,nonce,echostr);
PrintWriter pw=response.getWriter();
pw.write(result);
pw.flush();
return null;
}
I Googled and got that when using #Responsebody, Spring write messages to the body of response.
So what's the difference between them? Why the first way is Wrong?
An HTTP response consists of a status code, some headers, and a body. Using #ResponseBody means your method gives the content of the body, and nothing else. Using HttpServletResponse enables your method to set all aspects of the response, but is a little inconvenient to use.
You should use ResponseBody for returning some data structure. Since you need "only" String, you should change the return type of your method to void from String and remove ResponseBody annotation.
#RequestMapping(value="/userFollow", method= RequestMethod.GET)
public void weChatToken(HttpServletRequest request,String signature,String timestamp,String nonce,String echostr,HttpServletResponse response) throws IOException, DocumentException {
String result=weChatService.checkSignature(signature,timestamp,nonce,echostr);
PrintWriter pw=response.getWriter();
pw.write(result);
pw.flush();
}

download uploaded file using spring mvc abstractions (avoid using raw HttpServletResponse)

I am trying to add file uploading and downloading in my web application.
I am used to don't use raw HttpServletRequest and HttpServletResponse when I use spring mvc. But now I have following controller to download files.
public ModelAndView download(HttpServletRequest request, HttpServletResponse response) throws Exception {
int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
Files file = this.filesService.find(id);
response.setContentType(file.getType());
response.setContentLength(file.getFile().length);
response.setHeader("Content-Disposition","attachment; filename=\"" + file.getFilename() +"\"");
FileCopyUtils.copy(file.getFile(), response.getOutputStream());
return null;
}
As you can see I use HttpServletRequest and HttpServletResponse here.
I want to find way to avoid using of these classes. Is it possible?
The id parameter that you are getting from request can be substituted with the use of #RequestParam or #PathVariable. See bellow for an example of #RequestParam
public ModelAndView download(#RequestParam("id") int id) {
// Now you can use the variable id as Spring MVC has extracted it from the HttpServletRequest
Files file = this.filesService.find(id); // Continue from here...
}
And now the response part
#RequestMapping(value = "/download")
public ResponseEntity<byte[]> download(#RequestParam("id") int id) throws IOException
{
// Use of http headers....
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
InputStream is // Get your file contents read into this input stream
return new ResponseEntity<byte[]>(IOUtils.toByteArray(is), headers, HttpStatus.CREATED);
}

Missing header 'Authorization' of type [java.lang.String]

I have a client app that communicates to the spring server with REST type calls using basic authentication.
The controller method signature is below:
#RequestMapping(value = "/REST/clients", method = RequestMethod.POST)
protected ModelAndView postClients(#ModelAttribute("ClientsCommand") ClientsCommand cmd,
#RequestHeader("Authorization") String credentials) throws IOException {
...
}
The problem I have is that if no Authorization is present in the header I get an error:
Missing header 'Authorization' of type [java.lang.String]]
Whereas, I was kind of hoping the credentials string would just be empty. How do I stop the error from occurring and just receive a blank string if no authorization header entry was sent?
Try toggling required=false on the #RequestHeader.
#RequestMapping(value = "/REST/clients", method = RequestMethod.POST)
protected ModelAndView postClients(#ModelAttribute("ClientsCommand") ClientsCommand cmd,
#RequestHeader(value = "Authorization", required=false) String credentials) throws IOException {
...
}
When the #RequestHeader is configured as required, Spring won't map a request to your handler when the header isn't there. By making it optional, your handler will be invoked as you're hoping (i.e. regardless of the header's presence).

Categories