Learning Restful web service using Spring MVC and angularJS.
Background story:
I was doing some form submission particular PUT method I was getting 405 method not allowed..
Spring MVC PUT Request returns 405 Method Not Allowed
One of the answers stated to should change to from #Controller to #RestController much cleaner implementation.
Setup:
I use jspViewResolver to direct my pages.
app-dispatcher-servlet
// -- app-dispatcher-servlet
<!-- ViewResolver JSP -->
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/html/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
Like so
// -- Controller
#Controller
#RequestMapping(value="/spa")
public class spaController {
#RequestMapping(method = RequestMethod.GET)
public String pagIndex(Model model){
/* some code here */
return "spa"; // Goes to --> spa.jsp
}
}
Problem
But once I change #Controller to #RestController spa.jsp page doesn't show up just String 'spa' is returned....
Right now I created two controllers which I think is redundant... looks something like this
spaController -- handles all jsp pages
#Controller
#RequestMapping(value="/spa")
public class spaController {
#RequestMapping(method = RequestMethod.GET)
public String pagIndex(Model model){
/* some code */
model.addAttribute("bookForm", new Book());
return "spa";
}
}
spaRestController -- rest end point
#RestController
#RequestMapping(value="/spa")
public class spaRestController {
#Autowired
private BookDao bookDao;
// Get list of books
#RequestMapping(path="/booklist", method = RequestMethod.GET, produces="application/json")
public Map<String, Object> getListBooks(){
System.out.println("method called");
List<Book> books = bookDao.getBookList();
Map<String, Object> data = new HashMap<String, Object>();
data.put("results", books);
return data;
}
// Save only
#RequestMapping(path="/booklist/{id}", method = RequestMethod.PUT)
public String save(#PathVariable("id") Integer id, #RequestBody Book book, BindingResult result){
System.out.println("Save method clicked");
System.out.println(book);
System.out.println(result);
return null;
};
}
Question:
I think having two controllers is a bit redundant is there away to combine these two?
Is there a better way of handling this?
Thank you all...
Related
requirement is that i want request type scope in particular bean Omsdashboard.java .i have to submit the architecture of controller where i want every time request i want new object .so this can be achieve by request scope because controller is by default singleton that why i cant not handle this problem please explain it. thanks for giving your time.
beans class
Omsdashborad.java
#Component
public class OMSDashBoard implements Serializable{
controller class
I am using autowire but they give singleton object but i want another object when project is loaded both method call onload time first call below method then call first method.
#Autowired
private WebApplicationContext context;
private OMSDashBoard omsDashBoard;
public OMSDashBoard getOMSDashBoard() {
System.out.println("##2"+(OMSDashBoard) context.getBean("omsDashBoard"));
return (OMSDashBoard) context.getBean("omsDashBoard");
}
#Autowired(required = false)
public void setOmsDashBoard(#Qualifier("omsDashBoard") OMSDashBoard omsDashBoard) {
this.omsDashBoard = omsDashBoard;
#RequestMapping(value = "/stuck/order/{fromDate}/{toDate}/{requestType}", method = RequestMethod.POST)
public ResponseEntity<OMSDashBoard> getAllStcukOrdersByRequestType(#PathVariable("fromDate") String fromDate,
#PathVariable("toDate") String toDate, #PathVariable("requestType") String orderTypeCd) {
return new ResponseEntity<OMSDashBoard>(omsDashBoard, HttpStatus.OK);
}
#RequestMapping(value = "order/summary/{fromDate}/{toDate}", method = RequestMethod.POST)
public ResponseEntity<OMSDashBoard> getOrderSummaryDetails(#PathVariable("fromDate") String fromDate,
#PathVariable("toDate") String toDate) {
return new ResponseEntity<OMSDashBoard>(omsDashBoard, HttpStatus.OK);
}
step :
use scope(value="request") in omsdashboard.java
step-2
autowired
public AnnotationConfigWebApplicationContext context;
step-3
OMSDashBoard omsDashBoard = (OMSDashBoard) context.getBean(OMSDashBoard.class); in both method to get new object through bean.
I have referred to ->
Spring MVC how to display data from database into a table
My aim is to try and understand what is the syntax and process to create queries, and whether I'm correct.
The following code tries to display all Order entities.
#AutoWired
private OrderService orderService;
#RequestMapping("/")
//public String orderPage(Model model) {
// model.addAttribute("orderList", SomeApp.getStore().getOrderList());
// return "form/orderPage"};
// this is the code I am trying to translate below
#ResponseBody
public List<order> orderList(Map<String, Object> model) {
List<order> orderList = OrderService.findALl();
//orderRepository.findAll <- where does this come in? is it needed at all
return orderList;
}
If the Service layer is not being used, in my Repo do I only state
List<Order> findAll();
Additional Info:
Service layer is not used in this project and instead business logic will be in Controller (partly why I'm confused as to what code goes where)
You need to #Autowire the OrderRepository so that you can call orderRepository.findAll() in your Controller as shown below. For that, you also need to define the OrderRepository and Order Entity classes.
Controller:
#Controller
public class Controller {
#AutoWired
private OrderRepository orderRepository;
#RequestMapping("/")
#ResponseBody
public List<order> orderList(Map<String, Object> model) {
List<order> orderList = OrderService.findALl();
orderRepository.findAll();
return orderList;
}
}
Repository:
#Repository
public interface OrderRepository extends JpaRepository<Order, Integer> {
public Order findAll();
}
Entity:
#Entity
public class Order {
//add your entity fields with getters and setters
}
You can refer here for spring-data-jpa basic example.
I am trying to use the Around method around my rest controller using a logger class. I get the output "Before calling Controller","After calling controller" etc, but I don't get any return result in my postman.
The code works fine with #Before method and #After.
The ReST Controller looks like this.
#RestController("/")
public class DummyController {
#RequestMapping(value="hello",method=RequestMethod.GET)
public String dummyMethod() {
System.out.println("In Controller...");
return "Hello There";
}
}
This is the Aspect class.
#Aspect
#Component
public class Logger {
#Around("within(DummyController)")//Around Not working....
public void printMessage(ProceedingJoinPoint p) throws Throwable
{
System.out.println("Before Calling Method...");
p.proceed();
System.out.println("After calling method...");
}
The bean configuration is as below:
<mvc:annotation-driven />
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.aop.test"> </context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
My output is:
Before Calling Method...
In Controller...
After calling method...
But the webservice output is blank in postman instead of "Hello There". The status is "200 OK"
The code works as expected with other Advices like #Before,#After...
Any pointers on where the code went wrong?
Thanks in Advance..
change your Aspect to below and it should work.
#Aspect
#Component
public class Logger {
#Around("within(DummyController)")//Around Not working....
public Object printMessage(ProceedingJoinPoint p) throws Throwable
{
System.out.println("Before Calling Method...");
Object result = p.proceed();
System.out.println("After calling method...");
return result;
}
Notice that I made the advice return the object returned by ProceedingJoinPoint
I have an angularjs spring web app that returns a json. This is the url
http://localhost:8080/AngularJSPostFormSpringMVC/
The above is the output of the json url.
When I luanch the url in chrome web client it does not consume json even though it returns a status of 200 : 0k.
This is the out put
This is my controller code
public class SpringMVCController {
#RequestMapping(value = "/PostFormData", method = RequestMethod.POST)
public #ResponseBody
Person PostService(#RequestBody Person person) {
return person;
}
#RequestMapping(value = "/PostFormDataByParam", method = RequestMethod.POST)
public #ResponseBody Person PostFormDataByParam(HttpServletRequest request) {
Person person = new Person();
person.setName(request.getParameter("name"));
person.setName(request.getParameter("location"));
person.setName(request.getParameter("phone"));
return person;
}
Please what could be wrong?
create model
public class Person {
private int name;
private String location;
private String phone;
getter setter ...
dependencies
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
controller
#RequestMapping(value = "/PostFormDataByParam", method = RequestMethod.POST)
public #ResponseBody Person PostFormDataByParam(#RequestBody Person person, HttpServletRequest request) {
person.get ...
return person;
}
good luck ~
Change type of parameter define in method PostService, like this;)
#RequestMapping(value = "/PostFormData", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE})
public #ResponseBody
Person PostService(#RequestBody Person[] person) {
return person[0];
}
I have a spring application and I want to use aspects to perform some performance logging.
I want to only log methods annotated with #Measured, so I created an annotation as follows :
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Measured {
boolean logParameters() default true;
boolean logResponse() default true;
boolean measureTime() default true;
}
The aspect is as follows:
#Aspect
#Component
public class MeasuredAspect {
#Pointcut(value = "#annotation(com.waelawada.web.Measured)")
public void isMeasurableEvent(){
}
#Around(value = "isMeasurableEvent() && #annotation(measured)")
public void addEventToMDC(ProceedingJoinPoint joinPoint, Measured measured) throws Throwable{
String methodName = joinPoint.getSignature().getName();
long startTime = System.currentTimeMillis();
joinPoint.proceed(joinPoint.getArgs());
long endTime = System.currentTimeMillis();
if(measured.measureTime()){
MDC.put(methodName,endTime-startTime);
}
}
}
This works just fine for a method like
#Measured
public boolean getUser() {
}
Now I want to annotate a spring mvc controller method that is already annotated with #RequestMapping, but the apsect doesn't seem to detect it.
#Measured
#RequestMapping(value = "/activity", method = GET)
public final String userProfile(#ModelAttribute(USER) User user,
Model model) {
//Do Something
}
How can i make the aspect detect this method? I am using spring aop definded in the context xml file as <aop:aspectj-autoproxy proxy-target-class="false"/>