Issue with spring boot post call. Unable to call controller from client side - spring

I am bit new to spring boot and I have developed the following logic:
Here is my requirement. Just I wanted to upload images to tomcat server for that I have tried this logic with spring boot
#SpringBootApplication
public class MyApplication {
public static void main(String[] args) throws IOException {
new File(UploadController.uploadDir).mkdirs();
SpringApplication.run(MyApplication.class, args);
}
}
#RestController
public class UploadController() {
#RequestMapping("/test")
public String get(Model model) {
return "abc";
}
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String uploadFiles(#RequestParam("uploadedFiles") MultipartFile[] uploadedFiles) throws IOException {
for(MultipartFile f : uploadedFiles) {
File file = new File(uploadDir + f.getOriginalFilename());
f.transferTo(file);
}
return "redirect:/";
}
}
Here, get request is working fine. Here is the code for get
public static String get() throws IOException {
HttpURLConnection conn = null;
BufferedReader br = null;
try {
URL url = new URL("http://localhost:8080/test");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
return br.readLine();
} catch (MalformedURLException e) {
throw new IOException(e.getMessage());
} catch (IOException e) {
throw new IOException(e.getMessage());
} finally {
if (null != conn) {
conn.disconnect();
}
if (null != br) {
br.close();
}
}
}
But I am not sure how can I call post method. I tried with same logic with POST as request type. BUt not able to upload the images. Can anyone post me the code for upload from client side?

With JSP and Javascript, code will look like below:
JSP code:
<input name="media[]" type="file" id="xmlTemplate" multiple>
Javascript code:
var data = new FormData();
jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
data.append("uploadedFiles", file);
});
var json = '{' + .... + ']}';//Some JSON I was also passing alongwith files
data.append('estimateInfo', new Blob([json], {
type: "application/json"
}));
$.ajax({
type : "POST",
processData: false,
dataType: 'json',
data: data,
cache: false,
contentType: false,
url: 'createEstimates',
success: function(result) {
},
error: function(result) {
}
});
Controller code:
#RequestMapping(value = "/createEstimates", method = RequestMethod.POST, consumes = { "multipart/form-data" })
#ResponseBody
public EstimateResponse createEstimates(HttpServletRequest request,
#RequestPart("estimateInfo") EstimateInfo estimateInfo, #RequestPart("uploadedFiles") MultipartFile... files) {
}
If you want to send from Java client, then you can refer to Upload Files Programmatically

Related

I want to upload file without using multipart in spring boot, would be great if I could get you valuable suggestions on this

Shall I remove this from application.properties
spring.http.multipart.enabled=true
What should be my approach towards this file upload without using multipart?
This way, I'm able to uploading file using where I'm using multipart.
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam(value = "picture", required = false) MultipartFile multipartFile,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!multipartFile.isEmpty()) {
String multipartFileName = multipartFile.getOriginalFilename();
String format = multipartFileName.substring(multipartFileName.lastIndexOf("."));
try {
Path path = Paths.get(DOG_IMAGES_BASE_LOCATION + "/" + name + format);
byte[] bytes = multipartFile.getBytes();
File file = new File(path.toString());
file.createNewFile();
Files.write(path, bytes);
if (file.length() == 0) {
response = utility.createResponse(500, Keyword.ERROR, "Image upload failed");
} else {
String dbPath = path.toString().replace('\\', '/');
dog = new Dog();
dog.setName(name);
dog.setPicture(dbPath);
dog = dogService.dogCreation(dog);
response = utility.createResponse(200, Keyword.SUCCESS, "Image upload successful");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I want to do it without using multipart, what would you suggest?
This is what I've done till now to solve this
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam("picture") String picture,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!picture.isEmpty()) {
String dogPicture = picture;
byte[] encodedDogPicture = Base64.encodeBase64(dogPicture.getBytes());
String format = dogPicture.substring(picture.lastIndexOf("."));
try {
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I just have to say that this should probably only be used as a workaround.
On your frontend, convert the file to base64 in js:
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(evt) {
console.log(evt.target.result);
//do POST here - something like this:
$.ajax("/upload64", {
method: "POST",
contentType: "application/text"
data: evt.target.result
}
};
On the server with an example of a decoder - more decoding options here Decode Base64 data in Java
import sun.misc.BASE64Decoder;
#PostMapping("/upload64")
public String uploadBase64(#RequestBody String payload){
BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);
//use your bytes
}

Spring HttpRequestHandler + XMLHttpRequest

i have a problem HttpRequestHandler does not receive any data when i send post data by javascript. i want to receive value of content, but it does not work.
Here is javascript code:
function utils_saveElementAndGetId(url,content) {
var xhr = new XMLHttpRequest()
xhr.open("post", url, false);
xhr.send(content);
if (xhr.status != 200) {
alert(xhr.status + ': ' + xhr.statusText)
} else {
return xhr.responseText
}
}
here is code of HttpRequestHandler:
public class HeaderServlet implements HttpRequestHandler {
private static final Logger log = LoggerFactory.getLogger(HeaderServlet.class);
TemplateDao templateDao;
HeaderElementDao headerElementDao;
CheckboxElementDao checkboxElementDao;
#Autowired
public HeaderServlet(TemplateDao templateDao, HeaderElementDao headerElementDao, CheckboxElementDao checkboxElementDao) {
this.templateDao = templateDao;
this.headerElementDao = headerElementDao;
this.checkboxElementDao = checkboxElementDao;
}
public void handleRequest(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
String content = req.getParameter("content");
HeaderElement headerElement = new HeaderElement(content);
Long templateId = (Long) req.getSession().getAttribute("id");
Template template = templateDao.get(templateId);
headerElement.template = template;
headerElementDao.create(headerElement);
template.headerElements.add(headerElement);
templateDao.saveOrUpdate(template);
resp.setStatus(200);
resp.setContentType("text/plain");
resp.getOutputStream().println(headerElement.getId());
resp.flushBuffer();
}
}
I have solved the problem , the problem was in javascript side , i have just forgot to add xhr.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");

SignalR Authorize attribute not called

I have a hub that does not convert the token located at Authorization:Bearer eyjsdalfsadlfjffdafs... in the request header to an identity. The rest of the API works fine with standard http verbs however for some reason SignalR is not authorizing the token into a user.
public class ChatHub : Hub
{
[Authorize]
public override Task OnConnected()
{
// error context.user.identity.name =""
var userId = int.Parse(Context.User.Identity.Name);
return base.OnConnected();
}
....
}
Startup.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
JwtHandler - this part of the filter is not called when the client connects to the hub even though onConnect() is attributed with [Authorize]
public class JwtHandler : DelegatingHandler
{
private const string ISSUER = "Issuer";
private const string AUDIENCE = "Audience";
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
byte[] key = Convert.FromBase64String("SecretKey");
try
{
var headers = request.Headers;
if(headers.Authorization != null)
{
if(headers.Authorization.Scheme.Equals("Bearer"))
{
string jwt = request.Headers.Authorization.Parameter;
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
TokenValidationParameters parms = new TokenValidationParameters()
{
ValidAudience = AUDIENCE,
ValidIssuers = new List<string>(){ISSUER},
IssuerSigningToken = new BinarySecretSecurityToken(key),
};
SecurityToken validated = new JwtSecurityToken(jwt);
var principal = tokenHandler.ValidateToken(jwt, parms,out validated);
Thread.CurrentPrincipal = principal;
if(HttpContext.Current !=null)
{
HttpContext.Current.User = principal;
}
}
}
var response = await base.SendAsync(request, cancellationToken);
if(response.StatusCode == HttpStatusCode.Unauthorized)
{
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "error=\"invalid_token\""));
return response;
}
return response;
}catch (Exception)
{
var response = request.CreateResponse(HttpStatusCode.Unauthorized);
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "error=\"invalid_token\""));
return response;
}
}
}
Try validating the jwt token in the OWIN middleware. In your Startup.cs add:
public void Configuration(IAppBuilder app)
{
app.UseJwtBearerAuthentication(
new Microsoft.Owin.Security.Jwt.JwtBearerAuthenticationOptions() {
AllowedAudiences = new string[] { ALLOWEDAUDIENCE },
IssuerSecurityTokenProviders = new[] {
new SymmetricKeyIssuerSecurityTokenProvider(ISSUER, System.Convert.FromBase64String(cKey))
}
});
app.MapSignalR();
}

Wicket http post, get raw data from servletrequest?

I try do POST some data to a Wicket WebPage. This works fine if the data is in a form. However, I want to post the data with jQuery's ajax-post. I am unable to get this data in my Page-constructor.
This is my jquery command:
$.ajax({
type: "post",
cache: false,
url: "http://localhost:8888/testjson",
data: JSON.stringify({"aap":"noot"),
contentType: 'application/json',
success: function(ydata){alert("aap");},
failure: function(errMsg) {alert(errMsg);},
contentType: false,
dataType: "json"
});
The /testjson is a mounted WebPage.
public TestJsonApiPage( PageParameters pp )
{
try
{
byte[] data = IOUtils.toByteArray( ( (ServletWebRequest) TestJsonApiPage.this.getRequest() ).getContainerRequest().getInputStream() );
}
catch ( IOException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
This is the constructor. What I see happening is that the inputstream is empty. However, when debugging, I see the raw data that I posted in HttpServletRequest in the newWebRequest in my WicketApplication
tl;dr How to get the raw post data in Wicket Page?
It seems Page does something to the post-parameters.
The solution for my problem is to use a Resource.
public class MyResource extends AbstractResource
#Override
protected ResourceResponse newResourceResponse( Attributes attributes )
{
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setContentType( "text/json" );
resourceResponse.setTextEncoding( "utf-8" );
HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
try
{
this.json = IOUtils.toString( request.getInputStream() );
}
catch ( IOException e )
{
e.printStackTrace();
}
resourceResponse.setWriteCallback( new WriteCallback()
{
#Override
public void writeData( Attributes attributes ) throws IOException
{
OutputStream outputStream = attributes.getResponse().getOutputStream();
Writer writer = new OutputStreamWriter( outputStream );
writer.write( MyResource.this.json );
writer.close();
}
} );
return resourceResponse;
}

sending Json from servlet to javascript [duplicate]

This question already has answers here:
How should I use servlets and Ajax?
(7 answers)
Closed 2 years ago.
I am trying to send an json object array from a servlet to javascript .where I all get the array and parse .
my ajax call the servlet appropriately but unable to recieve the json array at the javascript end
please help
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
System.out.println("Post!!");
response.setContentType("application/json");//since sendign jsonArray toString
PrintWriter out = response.getWriter();
try {
Marker marker=new Marker( 40.72318,-74.03605);//
JSONArray arrayObj=new JSONArray();
arrayObj.add(marker);
System.out.println(marker.toString());
out.print(arrayObj);
} finally {
out.flush();
out.close();
}
}
This is my ajax call in javascript where I am trying to get the json object array form the servlet.
$.ajax({
url:'test',
dataType:'json',
type:'POST',
success:function(data){
<%System.out.println(" success");%>
console.log(data);
alert('got json hopefully');
alert(data);
//
},
error:function(jxhr){
<%System.out.println(" faliure");%>
console.log(jxhr.responseText);
}
});
This worked for me, below is ajax code.
$.ajax({
type : 'POST',
url : "URL",
data: {array: array},
success : function(response)
{
alert("Success "+response.message);
},
error : function(response)
{
alert("Error"+response.message);
console.log('Error');
}
});
Servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String[] array = request.getParameterValues("array[]");
request.setCharacterEncoding("utf8");
response.setContentType("application/json");
ArrayList<String> message = new ArrayList<String>();
message.add("response message goes here");
PrintWriter writer = response.getWriter();
JSONObject obj = new JSONObject();
obj.put("message",message);
response.setStatus(200);
//System.out.println(obj.get("message"));
writer.append(obj.toString());
writer.close();
}
For more details refer here
This is how I make requests to the servlet and respond back with json. I use google GSON library for java and I advise you use it too. https://code.google.com/p/google-gson/
$.ajax({
url: 'servletName', //the mapping of your servlet
type: 'POST',
dataType: 'json',
data: $('#someForm').serialize(),
success: function(data) {
if(data.isValid){
//maybe draw some html
}else{
//data is not valid so give the user some kind of alert text
}
}
This is the servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String someInput = request.getParameter("someInput");
Map map=new HashMap();
if(someInput!=null){ //or whatever conditions you need
map.put("isValid",true);
map.put("someInput",someInput);
}else{
map.put("isValid", false);
}
write(response,map);
}
private void write(HttpServletResponse response, Map<String, Object> map) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(new Gson().toJson(map)); //this is how simple GSON works
}
I hope this is clear. If not, ask me in the comments.

Resources