Spring MVC Controller show 404 - spring

All i need help
this is my simple controller when i try to hit the url on postman it's
show 404 => response can any one tell me why it's come. i'm using the spring-boot project.
#Controller
#RequestMapping(value = "/rtb")
public class RtbTestController {
#RequestMapping(value = {"/naveen", "/nabeel", "/harsh"}, method = RequestMethod.GET)
public ModelAndView rtbResponseValidator(HttpServletRequest request, HttpServletResponse response) {
HashMap<String, Object> model = new HashMap<String, Object>();
model.put("pakistan", "zindabad");
model.put("indian", "Zindabad");
return new ModelAndView("openRTB", model);
}
}

Try this:
#Controller
#RequestMapping(value = "/rtb")
public class RtbTestController {
#RequestMapping(value = {"/naveen", "/nabeel", "/harsh"}, method = RequestMethod.GET, headers= "Accept=application/json")
public ModelAndView rtbResponseValidator(HttpServletRequest request, HttpServletResponse response) {
HashMap<String, Object> model = new HashMap<String, Object>();
model.put("pakistan", "zindabad");
model.put("indian", "Zindabad");
return new ModelAndView("openRTB", model);
}
}

Related

how set the value in Model inside Spring MVC annotation Controller

#RequestMapping(value = "/excelDataView", method=RequestMethod.GET )
public ModelAndView getExcel(final HttpServletRequest request, final HttpServletResponse response){
log.info("Inside getExcel()");
List<DataValidationResults> dataValidationResults = new ArrayList<DataValidationResults>();
dataValidationResults = dataValidationDelegate.exportData(TaskId);
log.info("dataValidationDelegate.exportData(TaskId) value " + dataValidationDelegate.exportData(TaskId));
request.setAttribute("dataValidationResults", dataValidationResults);
return new ModelAndView(new ExcelDataView(), "dataValidationResultsModel", dataValidationResults);
}

Rest template giving null body and status 302

I am trying to consume a rest call in my mvc controller, however every time I do it returns a null body with http status as 302.Also I am using spring boot with spring security to get https.
I've followed code samples from here: http://websystique.com/springmvc/spring-mvc-4-restful-web-services-crud-example-resttemplate/
and Get list of JSON objects with Spring RestTemplate however none of these work
Can someone please point me in the right direction
Thank you,
REST
#RequestMapping(value = "/api/*")
#RestController
public class PostApiController {
static final Logger logger = LogManager.getLogger(PostApiController.class.getName());
private final PostService postService;
#Inject
public PostApiController(final PostService postService) {
this.postService = postService;
}
//-------------------Retrieve All Posts--------------------------------------------------------
#RequestMapping(value = "post", method = RequestMethod.GET)
public ResponseEntity<List<Post>> getAllPosts() {
List<Post> posts = postService.findAllPosts();
if(posts.isEmpty()){
return new ResponseEntity<List<Post>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
}
return new ResponseEntity<List<Post>>(posts, HttpStatus.OK);
}
}
Controller
#Controller
public class PostController {
static final Logger logger = LogManager.getLogger(PostController.class.getName());
public static final String REST_SERVICE_URI = "http://localhost:8080/api"; //"http://localhost:8080/api";
private final PostService postService;
#Inject
public PostController(final PostService postService) {
this.postService = postService;
}
#SuppressWarnings("unchecked")
#RequestMapping(value = "/getAll")
// public String create(#Valid Post post, BindingResult bindingResult, Model
// model) {
public ModelAndView getAll() {
// if (bindingResult.hasErrors()) {
// return "mvchome";
// }
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Post>> responseEntity = restTemplate.exchange(REST_SERVICE_URI+"/post",HttpMethod.GET, null, new ParameterizedTypeReference<List<Post>>() {});
// ResponseEntity<Post[]> responseEntity = restTemplate.getForEntity(REST_SERVICE_URI+"/post", Post[].class);
List<Post> postsMap = responseEntity.getBody();
MediaType contentType = responseEntity.getHeaders().getContentType();
HttpStatus statusCode = responseEntity.getStatusCode();
// List<LinkedHashMap<String, Object>> postsMap = restTemplate.getForObject(REST_SERVICE_URI+"/post", List.class);
// String s= REST_SERVICE_URI+"/post";
// logger.info(s);
if(postsMap!=null){
for(Post map : postsMap){
logger.info("User : id="+map.getUid());
}
}else{
logger.info("No user exist----------");
}
//List<Post> postList = postService.findAllPosts();
ModelAndView mav = new ModelAndView("mvchome");
mav.addObject("postsList", postsMap);
Post newpost = new Post();
mav.addObject("post", newpost);
return mav;
}
}
***** to fix my issue I modified my code to just do a redirect on select url paths instead of "/*"
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat =
new TomcatEmbeddedServletContainerFactory() {
#Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
//used to be just collection.addPattern("/*"); now I changed it to specify which path I want it to redirect
collection.addPattern("/mvchome/*");
collection.addPattern("/home/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(createHttpConnector());
return tomcat;
}
The http status 302 is usually caused by wrong url setting.
First, make sure that public ResponseEntity<List<Post>> getAllPosts() {} method is called (just print List<Post> result inside it).
If it's called properly and you can get the return value inside public ModelAndView getAll() {}.
The problem should be the directing setting of the public ModelAndView getAll() {} method.
Check if you make something wrong in your web.xml or spring configuration. Pay attention to the configuration which redirects to views and the url mapping of your dispatcher servlet.
If public ResponseEntity<List<Post>> getAllPosts() {} is called but you can't get the return value, then it should be the issues of directing setting of the public ResponseEntity<List<Post>> getAllPosts() {} method.
Check your spring configuration and web.xml for that. The possible cause usually will be the misuse of wildcard in the configuration and web.xml, or just unnoticed wrong mapping.

localhost:8080/ returns status 404 - Spring

This is my code:
#Controller
#RequestMapping("/")
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
As I understand when I send request to localhost:8080/ it should open localhost:8080/merchants, but it is not working. Anyone has any suggestions?
Your showMerchantsList method will be called when you send request to localhost:8080/merchants. And this method will you redirect again localhost:8080/merchants. But if you want send request as localhost:8080/ and direct you to localhost:8080/merchants, then you should create another method as this:
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView showMerchantsListWithoutRequestMapping() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
This method will redirect you to localhost:8080/merchants, when you called localhost:8080/
Normal way you should use
#Controller
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
As i understand your requirement silly way:
#Controller
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView model=new ModelAndView("redirect:/merchants");
return model;
}
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
Note: Because / always denotes to root.

How to use #ResponseBody to return a map<string, string>?

public class RestfulControllerImpl implements RestfulController {
#Override
#RequestMapping(value = "maptest", method = RequestMethod.GET)
#ResponseBody
public Object mapReturn() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", "test1");
map.put("sex", "male");
map.put("address", "1324");
map.put("old", "123");
return map;
}
}
I want to return a map<string, string> for the request, and it occurs
HTTP-406 not acceptable
How to implement the method to return a response body with a map and it shows in like a json object?
If your Controller only return json (REST API) then annotate Class with #RestController instead of #Controller. Then you don't need to add #ResponseBody annotation to each and every Endpoint. Since we cleared the problem with missing #ResponseBody Below code will do what you want.
#GetMapping("/maptest")
public ResponseEntity<?> mapReturn() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", "test1");
map.put("sex", "male");
map.put("address", "1324");
map.put("old", "123");
return ResponseEntity.ok(map);
}
Here ResponseEntity is wrapper for Http response. Since I declared here as ResponseEntity<?> I can return any Object as json. (It is good when you have return error response as another object) But if you sure that it will only return Map Object you can write it as ResponseEntity<Map> (If you have separate error handler)
Hope this is clear.
#RequestMapping(value = "maptest", method = RequestMethod.GET)
public ResponseEntity<?> mapReturn() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", "test1");
map.put("sex", "male");
map.put("address", "1324");
map.put("old", "123");
return new ResponseEntity(map, HttpStatus.OK); // you can change status code based on response
}
You can set up ResponseEntity details such as body, status or headers.
4XX is client side error
try add request headers
Accept:application/json
"HTTP-406 not acceptable" mostly deals with content negotiation you can also check headers in the browser when you face this kind of problem, solution can be obtained using Jackson or Gson Dependency
Client Side
var jsonData = '{"name":"John", "age":30, "city":"New York"}'
var obj = JSON.parse(jsonData);
$.ajax({
type : "POST",
url : "${pageContext.request.contextPath}/getJSON",
dataType: 'json',
cache:false,
async:false,
data : obj,
success: function(data){
console.log(data.name);
console.log(data.gender);
console.log(data.address);
}
});
Server Side:
#RequestMapping(value="/getJSON")
#ResponseBody
public String mapReturnUsingJackson() throws JsonGenerationException, JsonMappingException, IOException {
Map<String, String> hashMap = new HashMap<String, String>();
hashMap.put("name", "County");
hashMap.put("address", "Unknown");
hashMap.put("gender", "male");
String jsonJackson=new ObjectMapper().writeValueAsString(hashMap);
return jsonJackson;
}
//OR
#RequestMapping(value="/getJSON")
#ResponseBody
public String mapReturnUsingGSON() {
Map<String, String> hashMap = new HashMap<String, String>();
hashMap.put("name", "County");
hashMap.put("address", "Unknown");
hashMap.put("gender", "male");
String jsonStr = new Gson().toJson(hashMap);
return jsonStr;
}
Return map instead of object.
#RequestMapping(value = "maptest", method = RequestMethod.GET)
#ResponseBody
public Map<String,String> mapReturn() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", "test1");
map.put("sex", "male");
map.put("address", "1324");
map.put("old", "123");
return map;
}
Try changing the return type of the function to Map<String, String> and adding "produces" to the request mapping:
#RequestMapping(path="maptest", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public Map<String, String> test() {
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
return map;
}
#ResponseBody is use for returning string/json. You might wanted to use model, have a look at this
http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/ui/Model.html

spring boot setContentType is not working

I'm trying to return an image on spring-boot (1.2.2)
How should I set the content-type?
Non of the following are working for me (meaning that response headers are not containing 'content-type' header at all ):
#RequestMapping(value = "/files2/{file_name:.+}", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> getFile2(final HttpServletResponse response) throws IOException {
InputStream is = //someInputStream...
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.setContentType("image/jpeg");
InputStreamResource inputStreamR = new InputStreamResource(is);
return new ResponseEntity<>(inputStreamR, HttpStatus.OK);
}
#RequestMapping(value = "/files3/{file_name:.+}", method = RequestMethod.GET)
public HttpEntity<byte[]> getFile3() throws IOException {
InputStream is = //someInputStream...
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
return new HttpEntity<>(IOUtils.toByteArray(is), headers);
}
Firstly, you'll need to apply the #ResponseBody annotation in addition to #RequestMapping, unless you are using #RestController at the class level instead of just #Controller. Also, try the produces element of #RequestMapping e.g.
#RequestMapping(value = "/files2/{file_name:.+}", method = RequestMethod.GET, produces = {MediaType.IMAGE_JPEG_VALUE})
This should 'narrow the primary mapping' and ensure the correct content type is set. See the docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-requestmapping-produces
Got it... Had to add ByteArrayHttpMessageConverter to WebConfiguration class:
#Configuration
#EnableWebMvc
#ComponentScan
public class WebConfiguration extends WebMvcConfigurerAdapter {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> httpMessageConverters) {
httpMessageConverters.add(new ByteArrayHttpMessageConverter());
}
}
And the then my second attempt (getFile3()) was working correctly

Resources