In the development of springboot project, a requirement needs to forward the error Chinese information string to the corresponding controller for processing, so I first use urlencoder Encode (message, "UTF-8"), then splice the encoded string to the URL, and use httpservletresponse.Sendredirect("url") redirects to the target controller with the following code:
private void responseError(ServletResponse response, String message) {
try {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
message = URLEncoder.encode(message, "UTF-8");
httpServletResponse.sendRedirect("/unauthorized/" + message);
} catch (IOException e) {
e.printStackTrace();
}
}
In the controller, use #Requestmapping(value = "/unauthorized/{message}") to get the dynamic parameter message on the path. The code is as follows:
#RequestMapping(value="/unauthorized/{message}")
public ResultMap unauthorized(#PathVariable("message") String message){
return ResultMap.fail(message);
}
During the test, it is found that the encoded Chinese string is similar to the form of %E7%99%BB%E5%BD%95%E8%Ba%AB%E4%BB%BD%E5%A4%B1%E6%95%88. During redirection, the request keeps cycling. The controller cannot capture the request, and finally reports an error: exceeded maxredirects Probably stuck in a redirect loop.
However, after I remove % from the parameter string, the controller method can capture and process the request normally. Therefore, I guess #Requestmapping() cannot match the special character %. Does anyone have a solution?
Related
I am developing a servlet for JAVA EE and keep getting this error "Error Viewerpage.index method has more than one entity. You must use only one entity parameter."
#ApplicationPath("REST2")
#Path("/viewer")
public class Viewerpage extends Application {
private GlobalConfiguration globalConfiguration;
private ViewerService viewerService;
#GET
#Path(value = "/viewer")
public Response index(String filename, String page, HttpServletResponse response) throws IOException {
// set headers before we write to response body
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(MediaType.TEXT_HTML);
// render a page of a file based on a parameters from request
renderPage(filename, response.getOutputStream());
// complete response
response.flushBuffer();
String value = "redirect:index";
return Response.status(Response.Status.OK).entity(value).build();
}
private void renderPage(String filename, OutputStream outputStream) {
String filepath = "storage/" + filename;
// render first page
MemoryPageStreamFactory pageStreamFactory = new MemoryPageStreamFactory(outputStream);
HtmlViewOptions viewOptions = HtmlViewOptions.forEmbeddedResources(pageStreamFactory);
Viewer viewer = new Viewer(filepath);
viewer.view(viewOptions);
viewer.close();
}
}
Any ideas what cause this error?
When you declare a resource method, you can only have one parameter that is the request entity. The parameter without any annotations is considered the entity body. All other parameters must have some kind of annotation that specifies what it is and what should be injected. If they are query parameters, use #QueryParam. If it is a path parameter, use #PathParam. If it some other non-Param injectable (that is supported) e.g. HttpServletRequest, then use #Context. Other supported "Param" injectable types are #HeaderParam, #FormParam, #CookeParam, #MatrixParam, etc.
Think of the HTTP response that gets streamed to the client. You are sending it with
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(MediaType.TEXT_HTML);
renderPage(filename, response.getOutputStream());
response.flushBuffer();
But then, afterwards (when the response stream at most should be closed), you try to do something that looks like building a second response:
Response.status(Response.Status.OK).entity(value).build();
As every response can have only one set of header and body you cannot go back setting headers or sending a second response entity. That is what the error is about.
I'm creating a project in Java with Spring Boot.
The focus is to receive an image that is converted to a stream and that my code converts this image to a pdf file and sends this pdf back as a stream.
Despite the analysis, I can't get past the beginning, receiving the stream.. .
Here you'll see a snippet of my postman call to the running project
My Controller looks like this:
#RestController
public class Controller {
#PostMapping(value = "/convert/{format}", consumes = "application/octet-stream", produces = "application/octet-stream")
#ResponseBody
public void convert(RequestEntity<InputStream> entity, HttpServletResponse response, #PathVariable String format, #RequestParam Map<String, String> params) throws IOException {
if ("pdf".equalsIgnoreCase(format)) {
PDFConverter cnv = new PDFConverter();
/*cnv.convert(entity.getBody(), response.getOutputStream(), params);*/
response.setContentType("application/octet-stream");
response.getOutputStream().println("hello binary");
} else {
// handle other formats
throw new IllegalArgumentException("illegal format: " + format);
}
}
}
What do I overlook in this case?
I found the solution, in the controller I used RequestEntity<InputStream> entity, this gave the error. After changing this to HttpServletRequest request it worked.
#RestController
public class Controller {
#RequestMapping(value="/convert/{format}", method=RequestMethod.POST)
public #ResponseBody void convert(HttpServletRequest request, HttpServletResponse response, #PathVariable String format, #RequestParam Map<String, String> params) {
try{
if ("pdf".equalsIgnoreCase(format)) {
PDFConverter cnv = new PDFConverter();
response.setContentType("application/pdf");
cnv.convert(request.getInputStream(), response.getOutputStream(), params);
} else {
// handle other formats
throw new IllegalArgumentException("illegal format: " + format);
}
} catch (IllegalArgumentException | IOException e) {
e.printStackTrace();
}
}
}
As the error message tells you already, your content-type is not valid. You expecting a different content Type than you are sending off. Might be the problem that you append the charset definition to the request.
I think you are using commons-fileupload's streaming API. This won't work if spring.http.multipart.enabled=true, due to the request being pre-processed. Can you try setting spring.http.multipart.enabled=false and also change consumes = { MediaType.MULTIPART_FORM_DATA_VALUE },
#RequestMapping(value = {"sms"},method = RequestMethod.POST)
public string rplyMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
Body body = new Body.Builder("Response message").build();
Message sms =
new Message.Builder().body(body).build();
MessagingResponse twiml = new MessagingResponse.Builder().message(sms).build();
response.setContentType("application/xml");
try {
response.getWriter().print(twiml.toXml());
} catch (TwiMLException e) {
e.printStackTrace();
}
}
This is how I handle the twilio response message.I want to get the content from the response message. and i want to store it in the database.How I can get the content from the response message.
Twilio developer evangelist here.
When Twilio makes a request to your application it sends the parameters encoded as application/x-www-form-urlencoded in the body of the POST request.
I've never written Java Spring MVC before, so excuse me if this isn't spot on, but I believe you can then read those parameters out of the body using the #RequestParam annotation.
#RequestMapping(value = {"sms"},method = RequestMethod.POST)
public string rplyMessage(
HttpServletRequest request,
HttpServletResponse response,
#RequestParam("Body") String message,
#RequestParam("From") String from
) throws IOException {
storeMessage(from, message);
// respond to the request
}
The message body and the number that sent it are the parameters "Body" and "From", you can see all the available request parameters here. So, for example with the message, you set the argument to #RequestParam to the name of the parameter, then you set the type and what you want the variable to be called within the method, thus: #RequestParam("Body") String message.
I don't know how you plan to use the database, but that's what I can tell you. You can read more about #RequestParam here and see some Twilio Java and Spring tutorials here.
Let me know if that helps at all.
I want send を伴う出力となって to backend java code via http get request.
My get call url is http://localhost:8080/test/getID?id=%E3%82%92%E4%BC%B4%E3%81%86%E5%87%BA%E5%8A%9B%E3%81%A8%E3%81%AA%E3%81%A3%E3%81%A6
Java code:
#RequestMapping(value = "/getCaseId")
public ModelAndView showCaseId(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
String msg = request.getParameter("id");
System.out.println("URL:"+msg);
return new ModelAndView("showID", "idList", null);
}
Above piece of code prints URL:ãä¼´ãåºåã¨ãªã£ã¦.
So what's change i need to do get the exact Japanese text what i have passed from front end.
Try changing your msg line to:
String msg = new String(
request.getParameter("id").getBytes(StandardCharsets.ISO_8859_1),
StandardCharsets.UTF_8
);
If that will work it means that your application server (Tomcat? jetty?) is not configured correctly to handle UTF-8 in URLs.
If you use eclipse IDE, you need to check Text File encoding. Please check with the following figure.
The problem is that the submitted query string is getting mutilated on the way into your server-side script, because getParameter() uses ISO-8559-1 instead of UTF-8.
So i modified my code as below and now its working
#RequestMapping(value = "/getCaseId")
public ModelAndView showCaseId(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
String msg = new String(request.getParameter("id").getBytes("iso-8859-1"), "UTF-8")
System.out.println("URL:"+msg);
return new ModelAndView("showID", "idList", null);
}
I found this solution in http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.html/forum__lxgr-hi_i_am_havi.html.
Oh hello there, fellow SO members,
I have a web service that returns XML data using a simple get request that goes like this :
http://my-service:8082/qc/getData?paramX=0169¶mY=2
the service returns raw xml in the page according to the parameters' values.
I am trying to retrieve this data from a GET request in GWT using RequestBuilder, Request, etc.
However, the response gives me empty text, a Status code of ZERO (which doesn't mean anything and isn't supposed to happen), and so on.
Here's the simplified code that doesn't work.
public class SimpleXML implements EntryPoint {
public void onModuleLoad() {
this.doGet("http://my-service:8082/qc/getData", "0169", "2");
}
public void doGet(String serviceURL, String paramX, String paramY) {
final String getUrl = serviceURL + "?paramX=" + paramX + "&idTarification=" + paramY;
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, getUrl);
try {
Request response = builder.sendRequest(null, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
response.getStatusCode(); // Gives me 0 (zero) :(
}
#Override
public void onError(Request request, Throwable exception) {
// ... doesn't matter for this example
}
});
} catch (RequestException e) {
// ... doesn't matter for this example
}
}
}
I don't get why this wouldn't work, since this is REALLY simple, I've seen tutorials and they all show me this way of doing things..
Thanks in advance
The reason is, that browsers do not allow cross-site requests with AJAX (see Same Origin Policy).
This means, that you can only call a service on the same server, same port (using the same protocol) as your HTML page. If you want to perform cross-site requests, you can use JSONP, as explained in http://code.google.com/webtoolkit/doc/latest/tutorial/Xsite.html.