I have a stream of bytes for a pdf file which I have stored in a session.
#RequestMapping(value = "/start.htm")
public String start(HttpServletRequest request, Model model)
throws Exception
{
// do something
request.getSession().setAttribute(uniqueId,bytesOfaPDF);
return "jspname";
}
Now I have put this in my JSP.
<object id="COB" data="/retrievePdf.htm" type="application/pdf" width="100%" height="100%">
</object>
Now I have to write another method in my controller with the same mapping (retrievePdf) which will show PDF.
#RequestMapping(value="/retrievePdf.htm", method=RequestMethod.GET)
public void retrievePdf(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap)throws OSOSystemException
{
byte[] db = (byte[]) request.getSession().getAttribute(uniqueId);
response.getOutputStream().write(db);
response.setContentType("application/pdf");
response.setContentLength(db.length);
}
But I am not able to understand how I can pass uniqueId to retrievePdf?
How I can achieve this?
Thanks in advance.
Pass the unique ID as a query string in the URL
Store the unique id in request
#RequestMapping(value = "/start.htm")
public String start(HttpServletRequest request, Model model)
throws Exception
{
// do something
// storing uniqueId
request.getSession().setAttribute("uniqueId",uniqueId) ;
request.getSession().setAttribute(uniqueId,bytesOfaPDF);
return "jspname";
}
In Jsp append the URL dynamicaally:
<% String uniqueId=request.getSession().getAttribute("uniqueId") ;
String url = "/retrievePdf.htm?uniqueId="+uniqueId ;
%>
<object id="COB" data="<%=url%>" type="application/pdf" width="100%" height="100%">
</object>
Add requestParam for uniqueId in the below method and process it
#RequestMapping(value="/retrievePdf.htm", method=RequestMethod.GET)
public void retrievePdf(HttpServletRequest request, HttpServletResponse response, #RequestParam(value="uniqueId",required=true)String uniqueId,ModelMap modelMap)throws OSOSystemException
{
byte[] db = (byte[]) request.getSession().getAttribute(uniqueId);
response.getOutputStream().write(db);
response.setContentType("application/pdf");
response.setContentLength(db.length);
}
Thats all, it will work !!
Related
I have a method in my controller that directs to the page with comments.
All comments are related to a specific message. I use pathvariable to send messageID that I later use to get comments from my database.
#GetMapping("/showComments/{messageId}")
public String displayComments(#PathVariable Long messageId, #AuthenticationPrincipal User user, Model model) {
List<Comment> comments = commentService.showComments(messageId);
Message messageGotById = messageService.getMessageById(messageId);
model.addAttribute("comments", comments);
model.addAttribute("messageGot",messageGotById);
model.addAttribute("userId",user.getId());
return "listComments";
}
And then I have a method for fetching images from database
#GetMapping("/getImageComment/{id}")
public void showCommentImage(#PathVariable Long id, HttpServletResponse response) throws IOException {
response.setContentType("image/jpeg");
Message messageImage = messageService.getMessageById(id);
ImageInfo imageInfo = messageImage.getUsr().getImageInfo();
byte[] imageData = imageInfo.getImageData();
String encode = Base64.getEncoder().encodeToString(imageData);
InputStream is = new ByteArrayInputStream(imageData);
IOUtils.copy(is, response.getOutputStream());
}
listComments.html
<img th:src="#{'getImageComment/' + ${userId}}" height="55"
width="55">
Added the link I use to go to listComments.html
<a th:href="#{/showComments/{id}(id=${message.id})}">comment</a>
The issue here is that when there is a variable on URI in displayComments method, images are not displayed.
But without pathvariable everything works just fine.I cant understand what is the problem.
Followed dsp_user advice and used Server-relative URLs. Changed
<img th:src="#{'getImageComment/' + ${userId}}" height="55"
width="55">
to
<img class="rounded" th:src="#{'~/getImageComment/' + ${userId}}" height="55"
width="55">
And It finally worked for me.
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/froala-editor/2.7.6/js/froala_editor.pkgd.min.js"></script>
<script>
$(function() {
$('#edit').froalaEditor({
// Set the image upload URL.
imageUploadURL: 'upload_image',
imageUploadParams: {
id: 'my_editor'
}
})
});
</script>
<body>
<textarea id="edit" name="content"></textarea>
</body>
#PostMapping("/upload_image")
public void process(HttpServletRequest request,
HttpServletResponse response) throws Exception{
Map<Object, Object> responseData = null;
String linkName = "http://link";
responseData = new HashMap < Object, Object > ();
responseData.put("link", linkName);
// Send response data.
String jsonResponseData = new Gson().toJson(responseData);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
response.getWriter().write(jsonResponseData);
}
This doesn't return JSON to Froala editor. Please help.
Spring MVC makes this really simple. You just need the #ResponseBody annotation on the method to indicate you're returning the body which will be serialized and sent by the framework. Since the framework does it, headers and statuses are set appropriately. Also, I've removed unused parameters and set the Map's type properly.
#PostMapping("/upload_image")
#ResponseBody
public Map<String, String> process() throws Exception{
Map<String, String> responseData = new HashMap<>();
String linkName = "http://link";
responseData.put("link", linkName);
// Send response data.
return responseData;
}
Here's my controller below:
#RequestMapping(value="/upload", method=RequestMethod.PUT)
public ResponseEntity<String> handleFileUpload(
#RequestParam("file") MultipartFile file,
#RequestParam("data") String campaignJson,
Principal principal) throws JsonParseException, JsonMappingException, IOException {
I want to be able to receive a MultipartFile as well as a JSON string containing data associated to the file (title, description, etc).
I can get MultipartFile uploading to work on it's own, and I can receive a JSON string and parse it on its own, but when I have them together in 1 controller, it fails. Whenever I print out the String campaignJson it says [object Object] instead of the data that I'm sending (when I print out the data being sent in angular, it's in correct JSON format.)
I've tried #RequestBody, #RequestParam, #RequestPart, but to no avail.
My question is: How do I receive both a MultipartFile and data in the form of JSON in one Spring controller?
This worked for me :
#RequestMapping(value = "/{id}/upload", method = RequestMethod.PUT)
public DocumentResource uploadPut(#PathVariable("id") Long id,
MultipartHttpServletRequest request,
HttpServletResponse response) {
String next = request.getFileNames().next();
MultipartFile file = request.getFile(next);
.....
}
Edit :
Using the MultipartHttpServletRequest should not limit you in any way to use other #PathVariables or #RequestParams, so passing title and description should be possible.
I used it to upload multiple images with AngularJS and FileUploader
( angular-file-upload v1.1.5 )
like this
var uploader = new FileUploader({
url: config.apiUrl('/machine/' + $scope.id + '/images/'),
method: "post",
queueLimit: maxFiles
});
I'm trying to display an uploaded picture (which is now a byte array) on a jsp page. Now, the byte[] column exists in the database and has to be converted to an image.
This is what I've been trying:
Part of the table on jsp page:
<c:forEach var="user" items="${userList}">
<tr>
<td>${user.fileName}</td>
<td>
<img src="data:image/jpg;base64,${user.imageFile}" alt="No image">
</td>
Part of the controller that takes an array of bytes from a MultipartFile object:
#RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView userRegister(#ModelAttribute("user") #Valid User user, BindingResult result, ModelMap model, #RequestParam("fileData") MultipartFile fileData) throws Exception {
if (!fileData.isEmpty() && fileData != null) {
byte[] bytes = fileData.getBytes();
user.setFileName(fileData.getOriginalFilename());
user.setImageFile(bytes);
}
}
If any additional information is needed, please let me know. Thanks.
You can add a tranisent base64imageFile property to your User. It will hold the base64 encoded string of the image, which you can access in your jsp like
<img alt="img" src="data:image/jpeg;base64,${user.base64imageFile}"/>
And in your method you should do the encoding, somethig like
#RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView userRegister(#ModelAttribute("user") #Valid User user, BindingResult result, ModelMap model, #RequestParam("fileData") MultipartFile fileData) throws Exception {
if (!fileData.isEmpty() && fileData != null) {
byte[] bytes = fileData.getBytes();
user.setFileName(fileData.getOriginalFilename());
user.setImageFile(bytes);
byte[] encodeBase64 = Base64.encodeBase64(bytes);
String base64Encoded = new String(encodeBase64, "UTF-8");
user.setBase64image(base64encoded);
}
}
IOUtils and Base64 are a handy util classes from org.apache.commons, shouldn't have a problem finding
I am submitting a form using jquery in my Spring mvc.
this is the jquery call to submit form.
function uploadJqueryFormForEdit(documentId){
alert("ccc");
$('#result').html('');
$("#editDocumentForm").ajaxForm({
success:function(data) {
alert("ddd");
$('#result').html(data);
alert("eee");
//getProjectSegment('documents','DocumentSegment',projectId);
$('#editDocumentForm').remove();
},
error:function(e){
alert(e.responseText);
$("#msgDiv").html('Error');
},
dataType:"text"
}).submit();
}
And this is the form that I'm going to submit.
<form action="cont/uploadEdit?documentId=15&projectId=2" name="editDocumentForm" id="editDocumentForm" enctype="multipart/form-data" method="post">
When i'm using one parameter in action url, eg.
action="cont/uploadEdit?documentId=15"
it works fine. but when i'm using two parameters as
action="cont/uploadEdit?documentId=15&projectId=2"
it doesn't call to controller method correctly(not hitting that method at all)
here is the controller method
#RequestMapping(value = "cont/uploadEdit", method = RequestMethod.POST)
public #ResponseBody String uploadEdit(#ModelAttribute("sessionId") String sessionId,#RequestParam("documentId") int documentId,#RequestParam("projectId") int projectId,MultipartHttpServletRequest request, HttpServletResponse response, UploadedFile fileDetail,UserBean userbean,Model model) throws SessionException {
logger.info("uploadEdit");
}
why can't I use two parameters in action tag.?
this is the controller method that worked fine with first action
#RequestMapping(value = "cont/uploadEdit", method = RequestMethod.POST)
public #ResponseBody String uploadEdit(#ModelAttribute("sessionId") String sessionId,#RequestParam("documentId") int documentId,MultipartHttpServletRequest request, HttpServletResponse response, UploadedFile fileDetail,UserBean userbean,Model model) throws SessionException {
logger.info("uploadEdit");
}
Add params = {"documentId", "projectId"} attribute to the RequestMapping annotation
#RequestMapping(value = "cont/uploadEdit", params = {"documentId", "projectId"}, method = RequestMethod.POST)
public #ResponseBody String uploadEdit(#ModelAttribute("sessionId") String sessionId,#RequestParam("documentId") int documentId,#RequestParam("projectId") int projectId,MultipartHttpServletRequest request, HttpServletResponse response, UploadedFile fileDetail,UserBean userbean,Model model) throws SessionException {
logger.info("uploadEdit");
found the error:
In the form that we are going to submit (in my case "editDocumentForm") there should be no any other input tags with the same name as in action url variables,
eg if there is something like this,
<input type="hidden" id="projectId" name="projectId" value="somevalue"/>
it will make conflicts. So make sure that no conflicts occur.