Form submit via AngularJs with Spring - Annoation not mapped to request - java

I have to do a form submit through angularjs and java layer has to process the request.
Sample Request:
Request Header:
PUT /student/form HTTP/1.1
Host: mydomain
Connection: keep-alive
Content-Length: 154
Origin: mydomain
Accept-Language: en
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/plain, */*
X-Requested-With: XMLHttpRequest
Form Data:
------WebKitFormBoundaryJ8UG5IFHivltab5e
Content-Disposition: form-data; name="formData"
[object Object]
------WebKitFormBoundaryJ8UG5IFHivltab5e--
In Java,
#org.springframework.stereotype.Service
#Path("/student")
public class FormSubmitService {
#PUT
#Path("/form")
#Consumes({MediaType.MULTIPART_FORM_DATA})
public void saveForm(#Context HttpServletRequest request,
#RequestBody FormDomainRequest formDomainRequest) {
LOG.debug("requets from browser");
}
}
But i could not get the form data in request to map to my pojo class "FormDomainRequest"
Please let me know there is there any wrong in my service layer!

Related

Spring boot RestController PathVariable string has quotation marks appended

I am using a spring boot restcontroller that has a method with requestmapping of GET and it takes a string parameter. Parameter has to be mapped from the URL PathVariable such /method/{param}.
#ResponseStatus(HttpStatus.OK)
RequestMapping(value = "/method/{param}", method =
RequestMethod.GET)
public ResponseEntity findByName(#PathVariable String param){
logger.info(param);// this log has " before and after the string
String p = StringEscapeUtils.unescapeHtml4(param);
logger.info(p);
...
}
HTTP Request
GET /SampleDataService/method/vanilla HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
I do get the value param but it has the html escaped quotation marks appended to it.
For eg, if I call /method/vanilla I get "vanilla"
Right now I am using StringEscapeUtils.unescapeHtml4(param) and then replacing the quotes with empty string.
But I want to know if there is some spring boot configuration that can prevent extra quotes in string PathVariables.
In url having multiple parameters
#RequestMapping(value="/method/{param:.+}", method=RequestMethod.GET)
public ResponseEntity findByName(#PathVariable("param")String param){
....
}

Unable to configure CSRF in Spring not to face CORS error

Following the Spring Boot's Issue #5834, in order to setup the proper CORS and lift the error supporting all the origins I have the following code:
#Configuration
#EnableWebSecurity
public class SecurityAdapter extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http)
throws Exception
{
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http.authorizeRequests();
authorizeRequests.antMatchers("/logon_check").permitAll();
authorizeRequests.antMatchers("/logon").permitAll();
authorizeRequests.anyRequest().authenticated();
http
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.cors()
.and()
.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
// setAllowCredentials(true) is important, otherwise:
// The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
// setAllowedHeaders is important! Without it, OPTIONS preflight request
// will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
And
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter
{
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
}
}
But the OPTIONS preflight request returns 403:
XMLHttpRequest cannot load http://192.168.2.10:8080/logon_check. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.168.2.10:4200' is therefore not allowed access. The response had HTTP status code 403.
These are the request headers:
OPTIONS /logon_check HTTP/1.1
Host: 192.168.2.10:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: http://192.168.2.10:4200
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Safari/537.36
Access-Control-Request-Headers: x-requested-with
Accept: */*
Referer: http://192.168.2.10:4200/logon
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,fa;q=0.6
And response headers:
HTTP/1.1 403
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 20
Date: Mon, 26 Jun 2017 23:56:06 GMT
Can someone help me configure the Spring right so all origins are passed through?
I found a way to fix the problem but I'm not sure if this way of fixing is the right way of doing it or not.
After a couple of hours tracing Spring's code, I realized that the problem is with the HTTP headers that are allowed in the request. So changing the this line could resolve the problem:
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type", "X-Requested-With", "X-XSRF-TOKEN"));
In the above line, I've added "X-Requested-With", "X-XSRF-TOKEN" to the list of the headers allowed by the request to have. These two extra headers are the ones I needed to add. There might be some other cases / browsers which some other headers might be needed. So a general fix could be:
configuration.setAllowedHeaders(ImmutableList.of("*"));
But again, I'm not sure if this could be security risk or not.

Jersey 2 gzip compression not have Content-Encoding header in response

I have read this: compress-responses-in-jersey and have Jersey 2 config:
#ApplicationPath("/jaxrs/")
public class AppConfig extends ResourceConfig {
public AppConfig() {
super(AdvertisementResource.class, MultiPartFeature.class);
packages("jaxrs");
EncodingFilter.enableFor(this, GZipEncoder.class, DeflateEncoder.class);
}
}
I have header Request:
GET http://localhost:8081/jaxrs/admin-adblock
Accept:application/json
Cache-Control:no-cache
Content-Type:application/json
Authorization:Basic c21h...
Accept-Encoding:gzip,deflate
But header response are:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Server: Jetty(9.2.2.v20140723)
Header in response Content-Encoding:gzip is missing only Vary: Accept-Encoding is appear if I have:
EncodingFilter.enableFor(this, GZipEncoder.class, DeflateEncoder.class);
If I remove compression and comment EncodingFilter row response header are:
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.2.2.v20140723)
or this:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 369
Server: Jetty(9.2.2.v20140723)
I`m testing with Intellij Rest Client Tool and I`m not sure if I receive compressed response from server?
I have download jersey sources and set breakpoint here and debug rest service web application with Intellij it appears that CONTENT_ENCODING gzip is added here:
response.getHeaders().putSingle(HttpHeaders.CONTENT_ENCODING, contentEncoding);
but its missing in response header from Intellij Rest Client tool..
I have download SoapUI and test the same Rest requests response headers:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 204
Server: Jetty(9.2.2.v20140723)
The Intellij Rest Client Tool is hiding response headers Content-Encoding and Content-Length..
I have open new issue

Unsupported Content-type:application/json in java webservice call

I am able to set content type using cxf library but I don't know how to set Authorization header. Whenever I set user name and password then it set Authorization header and encode whole value and add Basic. I don't want to do this. I want to add Authorization header with plain string which ever I provide. Please help me to solve out this problem.
AMPServices services = new AMPServices();
CoreXmlPort coreXmlPort = services.getAMPSoapService();
Client client = ClientProxy.getClient(coreXmlPort);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy=httpConduit.getClient();
String contentType=httpClientPolicy.getContentType();
contentType="application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8";
httpClientPolicy.setContentType(contentType);
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("username");
authorizationPolicy.setPassword("password");
httpConduit.setAuthorization(authorizationPolicy);
It generates following request xml.
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: Basic aXNoaXAgcGIvd3NkZXZlbDowNzZhNjFjYTM5MDcxODAxODVjNWRkMjM2YTdkMzZhNGQ1ODg5OWFj
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I want this type of request
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: username;password
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I was not able to do it. Please help me to solve out this problem.
Thanks,
Awadhendra
I think you are trying to call is a RestFul Service, so that's why the server side always response with a different content type than you expected (json instead of soap/xml). Is your url endpoint based on http protocol? If yes, do you need send additional parameters to this url?
The issue here is that the client you are using to interact with Webservice expecting XML based Soap Messages , while the service is serving JSON as a return media.
Either convert your client to use the JSON format and communicate using that, or alternatively use the XML based endpoint , consult with webservice provider for that.

"PUT" request isn't processed

I have a jquery script that sends data to my spring controller using PUT type. But controller never gets hit. If i change PUT to POST everything works as expected, but i need to use exactly PUT. Could you please review my code and tell me what i am doing wrong?
jQuery
var values = $("form").serialize();
$.ajax({
type: "PUT",
url: "/user/" + elogin.val(),
async: false,
data: values,
success: function(resp) {\\doStuff}
})
Controller
#Controller
#RequestMapping(value = "/user")
public class RestController {
#RequestMapping(value = "/{userLogin}", method = RequestMethod.PUT)
#ResponseBody
public boolean updateUser(#PathVariable String userLogin,
#RequestParam("epassword") String password,
...)
throws ParseException {
if (...) {
return false;
}
\\doStuff
return true;
}
}
FireBug error message
400 Bad Request
Response Headers
Connection close
Content-Length 1072
Content-Type text/html;charset=utf-8
Date Tue, 03 Sep 2013 10:21:28 GMT
Server Apache-Coyote/1.1
Request Headers
Accept */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Content-Length 168
Content-Type application/x-www-form-urlencoded; charset=UTF-8
Cookie JSESSIONID=5A510B1FB82DA6F3DD9E9FA8D67A8295
Host localhost:8085
Referer http://localhost:8085/welcome
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0
X-Requested-With XMLHttpRequest
Error
HTTP Status 400 - Required String parameter 'epassword' is not present
type Status report
message Required String parameter 'epassword' is not present
description The request sent by the client was syntactically incorrect.
Solved by adding to web.xml
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Hi I dont know am correct or not but I think we cannot use PUT for jquery ajax
type (default: 'GET')
Type: String
The type of request to make ("POST" or "GET"), default is "GET". Note: Other HTTP request methods, such as PUT and DELETE, can also be used here, but they are not supported by all browsers.
check this
http://api.jquery.com/jQuery.ajax/

Categories

Resources